Запрос с идентификатором и другими полями по сравнению с запросом с идентификатором и проверкой других после

#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 создает индексы для комментариев. Но, похоже, в производительности вашего запроса доминируют объемы данных, а не поля вашего запроса. В любом случае, вы извлекаете данные, а затем принимаете решение в приложении