Как я могу оптимизировать этот запрос postgresql? - PullRequest
4 голосов
/ 22 июня 2011

Ниже приведен запрос postgres, который, кажется, занимает гораздо больше времени, чем я ожидал. Таблица field_instances индексируется как по form_instance_id, так и field_id, а таблица form_instances индексируется по workflow_state. Поэтому я подумал, что это будет быстрый запрос, но это займет вечность. Кто-нибудь может помочь мне интерпретировать план запроса и какие индексы добавить, чтобы ускорить его? Спасибо.

explain analyze
select form_id,form_instance_id,answer,field_id
from form_instances,field_instances
where workflow_state = 'DRqueued'
    and form_instance_id = form_instances.id
    and field_id = 'Book_EstimatedDueDate';
                                                                               QUERY PLAN                                                                                
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Hash Join  (cost=8733.85..95692.90 rows=9277 width=29) (actual time=2550.000..15430.000 rows=11431 loops=1)
   Hash Cond: (field_instances.form_instance_id = form_instances.id)
   ->  Bitmap Heap Scan on field_instances  (cost=2681.11..89071.72 rows=47567 width=25) (actual time=850.000..13690.000 rows=51726 loops=1)
         Recheck Cond: ((field_id)::text = 'Book_EstimatedDueDate'::text)
         ->  Bitmap Index Scan on index_field_instances_on_field_id  (cost=0.00..2669.22 rows=47567 width=0) (actual time=830.000..830.000 rows=51729 loops=1)
               Index Cond: ((field_id)::text = 'Book_EstimatedDueDate'::text)
   ->  Hash  (cost=5911.34..5911.34 rows=11312 width=8) (actual time=1590.000..1590.000 rows=11431 loops=1)
         ->  Bitmap Heap Scan on form_instances  (cost=511.94..5911.34 rows=11312 width=8) (actual time=720.000..1570.000 rows=11431 loops=1)
               Recheck Cond: ((workflow_state)::text = 'DRqueued'::text)
               ->  Bitmap Index Scan on index_form_instances_on_workflow_state  (cost=0.00..509.11 rows=11312 width=0) (actual time=650.000..650.000 rows=11509 loops=1)
                     Index Cond: ((workflow_state)::text = 'DRqueued'::text)
 Total runtime: 15430.000 ms
(12 rows)

Ответы [ 3 ]

4 голосов
/ 22 июня 2011

Когда вы говорите Таблица field_instances индексируется как по form_instance_id, так и по field_id Вы имеете в виду, что существуют отдельные индексы для form_instance_id и field_id для этой таблицы?

Попробуйте сбросить индекс на form_instance_id и поместить составной индекс на (form_instance_id, field_id).

Индекс работает, давая вам быстрый поиск, который говорит вам, где находятся строки, которые соответствуют вашему индексу. Затем он должен выбрать эти строки, чтобы сделать то, что вы хотите. Таким образом, вы всегда хотите, чтобы ваш индекс был как можно более конкретным. Если вы поместите два индекса в таблицу, у вас будет два разных способа поиска, но запрос, как правило, использует только один из них. Если вы поместите в таблицу индекс сцепленный , вы сможете эффективно просматривать первое поле индекса, первые два поля и т. Д. (Таким образом, объединенный индекс на (a, b) дает вам быстрый поиск на a, еще более быстрый поиск на a и b, но не помогает вам искать вещи на b)

Прямо сейчас он выясняет все возможные вещи в form_instances, которые имеют правильное состояние. Он отдельно вычисляет все field_instances, которые имеют правильный идентификатор поля. Затем он присоединяется к хешу. Для этого делает поиск хеша из одного набора результатов и сканирует другой на совпадения.

С моим предложением он должен выяснить все возможные form_instances интереса. Затем он перейдет к индексу и определит все field_instances, которые соответствуют и экземпляру формы и идентификатору поля, и затем найдет именно те результаты, которые вас интересуют. Поскольку индекс более конкретен, в базе данных будет меньше строк данных для обработки вашего запроса.

1 голос
/ 22 июня 2011

http://explain.depesz.com - это фантастический онлайн-инструмент, который помогает визуально определить горячие точки.Я вставил ваши результаты в инструмент и получил такой анализ: http://explain.depesz.com/s/VIk

Однако сложно что-то сказать конкретно, не видя ваших таблиц и индексов.

0 голосов
/ 22 июня 2011

Нужно знать данные, которые у вас есть в таблице, однако, просто взглянув на sql и имена столбцов, я бы порекомендовал

  1. вам действительно нужен индекс для workflow_state, если предположить, что элементы внутри него не могут быть уникальными - это может не улучшить выбор, но будет вставлять или обновлять ...
  2. попробуйте заставить field_id проверить первое условие в вашем операторе where
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...