У меня довольно серьезная проблема с производительностью со следующим утверждением, которое я не могу исправить самостоятельно.
Учитывая ситуацию
- У меня postgres 8.4База данных с установленным Postgis 1.4
- У меня есть геопространственная таблица с ~ 9 миллионами записей.Эта таблица имеет столбец (postgis) геометрии и столбец tsvector
- У меня есть индекс GIST для геометрии и индекс VNAME для столбца vname
- Таблица:
ANALYZE
'd
Я хочу исключить текстовый поиск to_tsquery
в подмножестве этих геометрий, который должен вернуть мне все идентифицированные идентификаторы.
Область для поиска ограничит 9 миллионов наборов данныхпримерно 100.000, и набор результатов ts_query
внутри этой области, скорее всего, выдаст выходной сигнал 0..1000 записей.
Проблема
Анализатор запросов решает, чтоон хочет сначала выполнить растровое индексное сканирование для vname, а затем объединить и наложить фильтр на геометрию (и другие условия, которые я имею в этом утверждении)
Выходные данные Query Analyzer:
Aggregate (cost=12.35..12.62 rows=1 width=510) (actual time=5.616..5.616 rows=1 loops=1)
-> Bitmap Heap Scan on mxgeom g (cost=8.33..12.35 rows=1 width=510) (actual time=5.567..5.567 rows=0 loops=1)
Recheck Cond: (vname @@ '''hemer'' & ''hauptstrasse'':*'::tsquery)
Filter: (active AND (geom && '0107000020E6100000010000000103000000010000000B0000002AFFFF5FD15B1E404AE254774BA8494096FBFF3F4CC11E40F37563BAA9A74940490200206BEC1E40466F209648A949404DF6FF1F53311F400C9623C206B2494024EBFF1F4F711F404C87835954BD4940C00000B0E7CA1E4071551679E0BD4940AD02004038991E40D35CC68418BE49408EF9FF5F297C1E404F8CFFCB5BBB4940A600006015541E40FAE6468054B8494015040060A33E1E4032E568902DAE49402AFFFF5FD15B1E404AE254774BA84940'::geometry) AND (mandator_id = ANY ('{257,1}'::bigint[])))
-> Bitmap Index Scan on gis_vname_idx (cost=0.00..8.33 rows=1 width=0) (actual time=5.566..5.566 rows=0 loops=1)
Index Cond: (vname @@ '''hemer'' & ''hauptstrasse'':*'::tsquery)
, который вызывает много операций ввода-вывода - AFAIK Было бы разумнее сначала ограничить геометрию, а затем выполнить поиск vname.
Попытки решения
Комудостичь желаемого поведениянаш я попытался
- Я поместил geom @@
AREA
в подвыбор -> Не изменил план выполнения - Я создал временное представление с нужным подмножеством области -> Не изменил план выполнения
- Я создал временную таблицу нужной области -> Создание занимает 4 ~ 6 секунд, что еще больше ухудшило ситуацию.
Кстати,извините за то, что не опубликовал реальный запрос: я думаю, что мой босс действительно рассердился бы на меня, если бы я это сделал, также я ищу больше теоретических указателей для кого-то, чтобы исправить мой фактический запрос.Пожалуйста, спросите, нуждаетесь ли вы в дополнительных разъяснениях
РЕДАКТИРОВАТЬ
У Ричарда было очень хорошее замечание: вы можете добиться желаемого поведения Планировщика запросов с помощью width
заявление.Плохо то, что эта временная таблица (или CTE) портит индекс vname, поэтому в некоторых случаях запрос ничего не возвращает.
Мне удалось это исправить, создав новое vname на летус to_tsvector()
, но это (слишком) дорого - около 300 - 500 мс на запрос.
Мое решение
Я прекратил поиск по vname и пошел с простымLIKE('%query_string%')
(10-20 мс / запрос), но это быстро только в моей среде.YMMV.