#python #django #relational-database
#питон #джанго #реляционная база данных
Вопрос:
Для большого количества сообщений быстрее (и, следовательно, лучше) захватить объект только с идентификатором, а затем проверить, соответствует ли пользователь, не так ли?
# Option A
post = get_object_or_404(Post, id=post_id, owner=request.user)
# Option B
post = get_object_or_404(Post, id=post_id)
if post.owner != request.user:
raise Http404()
Ответ №1:
Когда вы говорите «большая база данных», вы имеете в виду «широкую таблицу» с большим количеством полей или «большую таблицу» с большим количеством строк?
Я предполагаю, что вы хотели сказать «широкая таблица» с большим количеством полей.
Производительность выборки из базы данных зависит от нескольких факторов:
- какие столбцы вы извлекаете,
- какой запрос вы используете для извлечения,
- критерии фильтрации,
- план запроса, используемый механизмом базы данных,
- запрошенные столбцы уже есть в индексе или нужно извлечь страницу базы данных и т.д.,
Ваш пример относится к извлечению записи по идентификатору, который является первичным ключом. Вы извлекаете владельца и post_id. Хотя вы не показали это в примере, вы, вероятно, используете другие поля записи (для отображения и т.д.). Таким образом, очень вероятно, что будет извлечен индекс первичного ключа и будет выполнен поиск страницы базы данных также потому, что в индексе PK нет поля owner или других запрашиваемых полей.
Таким образом, не имеет значения, используете ли вы вариант A или B, вы получите аналогичную производительность.
В общем случае, если таблица содержит M полей и вы запрашиваете N полей (включая все поля в предложении where), причем N намного меньше M, вы можете избежать поиска по странице базы данных, индексируя N полей, чтобы запрос мог быть выполнен непосредственно из индекса. Это увеличивает накладные расходы на вставки и обновления, и они будут медленнее, но ваши чтения будут быстрее.
Комментарии:
1. Спасибо вам за ваш ответ. Я имел в виду таблицу с большим количеством строк и отредактировал вопрос, чтобы прояснить это. Неужели это по-прежнему не имеет никакого значения? Я не создаю никаких индексов, но я не знаю, делает ли Django это автоматически.
2. Нет, это не имеет значения. Производительность вашего запроса ограничена объемом данных. Итак, если вы хотите post с id 12345, database engine должен будет выполнить поиск по индексу первичного ключа для 12345, чтобы найти, какая страница БД содержит эту строку, а затем проверить кэш БД, присутствует ли эта страница. Если страницы нет в кэше, ему придется загрузить страницу в кэш, а затем вернуть результаты вашего запроса. Я не знаю, как Django создает индексы для комментариев. Но, похоже, в производительности вашего запроса доминируют объемы данных, а не поля вашего запроса. В любом случае, вы извлекаете данные, а затем принимаете решение в приложении