Создайте службу, которая должна поддерживать что-то вдоль линий системы отслеживания случаев. Вот наша модель:Производительность django при запросе моделей со многими внешними ключами?
class Incident(models.Model):
title = models.CharField(max_length=128)
category = models.ForeignKey(Category)
status = models.ForeignKey(Status)
severity = models.ForeignKey(Severity)
owned_by = models.ForeignKey(User, related_name="owned_by", null=True, blank=True)
next_action = models.ForeignKey(IncidentAction)
created_date = models.DateTimeField()
created_by = models.ForeignKey(User, related_name="opened_by")
last_edit_date = models.DateTimeField(null=True, blank=True)
last_edit_by = models.ForeignKey(User, related_name="last_edit_by", null=True, blank=True)
closed_date = models.DateTimeField(null=True, blank=True)
closed_by = models.ForeignKey(User, related_name="Closed by", null=True, blank=True)
Потому что есть много внешних ключей втянуты в эту модель, она делает для интересных запросов SQL. Мы использовали в качестве пробной версии djblets data grid и панель инструментов отладки django и с тревогой встретили огромное количество запросов, каждый раз добавляя новый столбец для представления, который использует внешний ключ, в основном этот тип рабочего процесса запроса :
#prepare the grid
select * from incident_table;
#render each row
for each row in incident table
for each column that is a foreign key select row from foreign table with id
Это делает дополнительный запрос на выборку в строке для каждого столбца, который пытается тянуть свойство для внешнего ключа.
Я думаю, что это универсальная проблема с django и его ORM в отношении вытягивания свойств из моделей внешнего ключа для отображения. В качестве теста я сбросил сетку данных и просто выполнил простой список свойств для набора запросов, и аналогичным образом увидел запрос.
Мы хотим увеличить это, когда тонны пользователей поражают модель. В сравнении с этим я сделал аналогичную точку зрения для модели User, и ее полное отображение просто выполняется с одним запросом, потому что, если вы только вытаскиваете поля из данной модели, это не делает дополнительного удара db за дополнительный столбец.
Некоторые оптимизации мы пытались были:
- django-orm-cache: Не похоже на работу с Джанго 1.0.4
- django-caching: Это хорошо работает для кэширования часто запрашивается моделям кэширования уровня
- вид с memcached
- Редактировать: Использование select_related() может ускорить отрисовку шаблона, не возвращаясь обратно в базу данных обратно, но похоже, что внешние ключи просто глава времени на исходном запросе с использованием единственного запроса на внешний ключ. Кажется, что переместил запрос на несколько баз данных раньше времени.
Но есть некоторые более глубокие вопросы, мы вымогательство мудрость толпы на:
- Для моделей с тоннами внешних ключей, что это лучший способ сделать это эффективно запрос, чтобы получить свойства от внешних ключей?
- Является ли кэширование зависимых моделей единственным способом использования вышеуказанных систем кэширования ORM?
- Или это стандартный случай перерастания ORM и необходимость свертывания собственного пользовательского sql-запроса с объединениями для получения максимально возможного выходного потока данных?
Похожие вопросы, поднятые проблемы на кэширование и внешних ключей:
DB/performance: layout of django model that rarely refers to its parent more than once, Django ORM: caching and manipulating ForeignKey objects:
А, да. Я стою очень исправлен - похоже, что datagrid фактически игнорирует любые оптимизации, предоставляемые поставляемым набором запросов, и выполняет собственные поисковые запросы. Независимое тестирование моей модели с вашим примером сделало преимущества select_related() понятными как день. Благодаря! – dmyung