2013-02-27 5 views
5

У меня есть устаревший код, который использует вложенный запрос ORM, который производит запрос SQL SELECT с JOIN, и условия, которые также содержат SELECT и JOIN. Выполнение этого запроса занимает огромное время. Кстати, когда я выполняю этот запрос в необработанном SQL, взятом из Django_ORM_query.query, он выполняется с разумным временем.Оптимизация Django: вложенные запросы и запросы поиска

Каковы наилучшие методы оптимизации в таких случаях?
Будет ли запрос работать быстрее, если я буду использовать отношения ManyToMany и ForeignKey?

+0

Если вы говорите, что тот же SQL-код работает нормально при запуске вручную, вам не нужно оптимизировать этот код. – wRAR

+0

Проблема заключается в том, что сервисы запросов для извлечения элементов из каталога с указанными параметрами, а также он использует модели CMS, у которых есть некоторые, которые не так понятны для понимания конкретных функций. – user2115719

ответ

5

В случае сомнений используйте raw SQL. Это полностью действительная оптимизация в мире Django.

+1

Я боялся сказать это, потому что думал, что это мой грязный маленький секрет. – GordonsBeard

+0

Метод [extra] (https://docs.djangoproject.com/en/dev/ref/models/querysets/#extra) имел мою спину, охваченную в большинстве ситуаций, ORM в целом, по-видимому, охватывает более 90% случаи использования. Если это слишком много хлопот, хотя исходный SQL - это путь. Все в меру, я видел ужасный код, где люди, похоже, не знали, что ORM даже существует. – Matt

+0

До сих пор мне еще нужно было использовать 'raw()' или 'extra()'; когда у меня была проблема с производительностью, разумное использование 'select_related()', 'prefetch_related()' (или в более раннем Django, эквивалентное 'prefetch_related') всегда возвращало вещи на один-второй барьер для меня (одна секунда мой лимит для приемлемого времени создания страницы). Имейте в виду, что использование запроса 'raw()' может ограничивать независимость вашей базы данных. –

7

Проблема с производительностью в Django обычно вызвана следующими отношениями в цикле, которые вызывают несколько запросов к базе данных. Если у вас установлено django-debug-toolbar, вы можете проверить, сколько запросов вы делаете, и выяснить, какой запрос нужно оптимизировать. Панель инструментов отладки также показывает время каждого запроса, что необходимо для оптимизации django, вы много пропускаете, если его не установили или не использовали.

Как правило, вы решаете проблему следующих отношений, используя select_related() или prefetch_related().

На странице обычно должно быть больше 20-30 запросов, и это серьезно повлияет на производительность. На большинстве страниц должно быть только 5-10 запросов. Вы хотите уменьшить количество запросов, потому что поездка туда и обратно является убийцей номер один для производительности базы данных. В общем случае один большой запрос быстрее, чем 100 небольших запросов.

Убийца номер два по производительности базы данных намного реже, хотя иногда это происходит из-за методов, которые уменьшают количество запросов. Ваш запрос может быть просто слишком большим, если это так, вы должны использовать defer() или only(), чтобы не загружать большие поля, которые, как вы знаете, вы не будете использовать.

+0

Главная страница, на которой мне нужно оптимизировать, загружается с 400 + запросами :) – user2115719

+1

Да ... это WAY слишком много запросов. Слишком много. Нам нужно будет увидеть ваши модели, шаблоны и представления, чтобы сказать вам лучший способ сделать это. –

+0

@ user2115719: Я согласен, что слишком много запросов, попробуйте проверить, можете ли вы предварительно загрузить связанные объекты с помощью select_related или prefetch_related. –

Смежные вопросы