Но я хотел бы знать о втором.Проводится ли поиск по всей таблице изображений в базе данных, чтобы найти все изображения с post = p, или информация доступна, когда я получаю p в первом запросе?
Краткий ответ : по умолчанию ForeignKey
добавляет индекс, что делает поиск довольно быстрым (логарифмическое по количеству значений и линейное по количеству обратных записей).
Это зависит от того, создает ли база данных индексна ForeignKey
.По умолчанию Django будет создавать индекс.Это означает, что он хранит не только строки таблицы, но также структуру данных, которая позволяет быстро искать все строки, имеющие определенное значение.
Реализация индекса может зависеть от базы данных.В MySQL по умолчанию используется BTREE
, это означает, что для поиска значения требуется приблизительно O (log n) для получения коллекции и O (k) с k количеством элементов с этим внешним ключом для получения всех.Но существуют и другие структуры индекса, например, какая-то хеш-таблица, которая даже позволяет (немного) ускорить поиск, хотя, например, хеш-таблица не будет настолько эффективной для извлечения всех элементов с ForeignKey
меньше заданного числа.
Вы также можете добавить индекс для других столбцов, например:
class Post(models.Model):
name = models.CharField(max_length=25<b>, db_index=True</b>, unique=True)
Так что теперь получение всех Post
объектов с именем с заданным именем также будет выполняться быстрее.
Использование индексов, конечно, не «бесплатно»: это означает, что каждый раз, когда вы вставляете или удаляете запись, индекс также должен изменяться (обычно для этого также требуется O (log n) ).Если вы обновляете запись, изменяя значение внешнего ключа, этот индекс также необходимо изменить.Таким образом, индексы обеспечивают значительное ускорение, но следует стремиться размещать индексы только в столбце, для которого часто выполняется поиск, поскольку в противном случае стоимость «обслуживания» индекса может быть больше, чем выигрыш от ускорения процесса поиска.