Простой запрос работает годами, а потом вдруг очень медленно - PullRequest
7 голосов
/ 26 ноября 2011

У меня был запрос, который работал нормально около 2 лет.Таблица базы данных имеет около 50 миллионов строк и медленно растет.На прошлой неделе один из моих запросов перешел от почти мгновенного возврата к выполнению нескольких часов.

Rank.objects.filter(site=Site.objects.get(profile__client=client, profile__is_active=False)).latest('id')

Я сузил медленный запрос до модели ранга.Кажется, что-то связано с использованием метода latest ().Если я просто запрашиваю набор запросов, он сразу же возвращает пустой набор запросов.

#count returns 0 and is fast
Rank.objects.filter(site=Site.objects.get(profile__client=client, profile__is_active=False)).count() == 0
Rank.objects.filter(site=Site.objects.get(profile__client=client, profile__is_active=False)) == [] #also very fast

Вот результаты выполнения EXPLAIN.http://explain.depesz.com/s/wPh

И ОБЪЯСНИТЕ АНАЛИЗ: http://explain.depesz.com/s/ggi

Я пытался пылесосить стол, без изменений.В поле "site" уже есть индекс (ForeignKey).

Странно, если я выполню этот же запрос для другого клиента, у которого уже есть объекты Rank, связанные с его учетной записью, запрос снова очень быстро возвращается.,Так что кажется, что это проблема, только если у него нет объектов Rank для этого клиента.

Есть идеи?

Версии: Postgres 9.1, Django 1.4 svn trunk rev 17047

Ответы [ 2 ]

0 голосов
/ 26 ноября 2011

Ну, вы не показали фактический SQL, так что это затрудняет уверенность.Но вывод объяснения предполагает, что он считает, что самый быстрый способ найти совпадение - это сканировать индекс «id» в обратном направлении, пока не будет найден клиент, о котором идет речь.это, вероятно, не глупый выбор.Однако всегда существует вероятность того, что запись конкретного клиента окажется в самом конце этого поиска.

Итак, сначала попробуйте две вещи:

  1. Запустите анализ нав рассматриваемой таблице, посмотрите, дает ли это планировщику достаточно информации.
  2. Если нет, увеличьте статистику (ALTER TABLE ... SET STATISTICS) для рассматриваемых столбцов и проведите повторный анализ.Посмотрите, так ли это.

http://www.postgresql.org/docs/9.1/static/planner-stats.html

Если это все еще не помогает, то рассмотрите индекс на (client, id) и отбросьте индекс на id (если нетнужно в другом месте).Это должно дать вам молниеносные ответы.

0 голосов
/ 26 ноября 2011

latests обычно используется для сравнения дат, возможно, вам следует попробовать упорядочить по id desc, а затем ограничить его одним.

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