Вопрос о вложенных коллекциях в Django и эффективности запросов - PullRequest
6 голосов
/ 13 апреля 2009

Я вижу много ответов, подобных этому:

Печать списка лиц с несколькими домами в каждом доме с более чем одним

Я попробовал этот ответ с похожими моделями, и это кажется ужасно неэффективным способом сделать это. Кажется, что каждая итерация делает отдельный запрос, иногда приводящий к тысячам запросов к базе данных. Я понимаю, что вы можете кэшировать наборы запросов, но это все равно кажется очень неправильным. Итак, вопрос в том, используете ли вы этот метод? Если нет, то как ты это делаешь?

Ответы [ 2 ]

6 голосов
/ 13 апреля 2009

Это очень хороший вопрос, и он не ограничивается рамками Django ORM.

Я всегда чувствую, что важно помнить некоторые проблемы, которые решает инфраструктура объектно-реляционного отображения (ORM):

  • Объектно-ориентированный CRUD : Если остальная часть приложения основана на строгих объектно-ориентированных принципах, доступ к постоянству данных с использованием объектов делает код намного более связным, внутренне согласованным и иногда короче.

  • Инкапсуляция персистентного уровня : ORM обеспечивает прозрачный уровень в вашем приложении для доступа к БД. Он включает в себя все функции, необходимые для чтения / записи данных в одном месте, воплощение так называемого принципа СУХОЙ (не повторяйся). Это делает несколько вещей намного проще: изменения модели , потому что весь код выбора и вставки / обновления, обращенный к БД, находится в одном месте, а не во всем приложении, безопасность , потому что все БД доступ осуществляется через одно местоположение и тестирование , потому что легко смоделировать ваши модели данных и доступ, если они четко очерчены.

  • Безопасность SQL : Хотя использование исходного SQL-кода легко защитить от атак внедрения и т. Д., Еще проще, если у вас есть ORM-инфраструктура в качестве единой точки контакта с БД, которая делает это для вам, так что вам никогда не придется об этом думать.

Обратите внимание, что скорости нет в списке. ORM - это уровень косвенности между вашим кодом и базой данных. Мы, конечно, считаем, что разработчики ORM ответственны за написание среды, которая производит хорошие операторы SQL, но ORM предназначен для обеспечения эффективности на уровне кода и архитектуры, а не эффективности исполнения. Разработчик, прочитавший основную книгу по SQL, всегда сможет повысить производительность, общаясь непосредственно с БД.

Конечно, есть стратегии противодействия этому, и в Django это, как уже упоминал Озан, select_related() и кэширование сайта / вида / разного, но они не дадут вам такой же производительности, как прямой оператор SQL. Из-за этого я никогда не использовал бы среду ORM, которая не предоставляет некоторый механизм для выдачи необработанного оператора SQL в тех случаях, когда мне нужна скорость. Например, я часто прибегаю к необработанному SQL при создании большого отчета из базы данных, который объединяет множество таблиц; способ ORM может занимать минуты, способ SQL - секунды.

Сказав это, я никогда не начинаю беспокоиться о каждом отдельном запросе. Мой совет для всех, кто приходит на уровень ORM: не делайте няней доступа к базе данных ORM. Напишите свое приложение или модуль, а затем профилируйте его, настраивая те области, которые действительно нуждаются в повышении производительности, или используя caching / select_related, чтобы уменьшить общую непринужденность вашего приложения.

4 голосов
/ 13 апреля 2009

Вы можете использовать метод набора запросов select_related () , чтобы уменьшить количество запросов к базе данных. Вы также можете указать глубину, поэтому в данном примере, если модель телефонного номера имела дополнительные внешние связи, вы бы использовали select_related (deep = 2), чтобы избежать выбора дополнительных «уровней» связанных объектов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...