2012-07-01 5 views
5

У меня есть две таблицы, которые я бы хотел пересечь. Первая таблица составляет около 50 миллионов точек, а вторая - многоугольный слой всех стран мира. Я хочу получить все точки, которые пересекаются с этим многоугольником.Postgresql Пространственный запрос слишком медленный

SELECT d.id, d.geom 
FROM export d, world_boundaries b 
WHERE (b.cntry_name = 'UK') 
    AND d.date_inserted >= '2012-06-01' 
    AND d.geom && b.wkb_geometry 
    AND intersects(d.geom, b.wkb_geometry); 

Этот запрос очень прост, но требуется более 4 часов. У меня есть индексы GIST, построенные на столбце геометрии для каждой таблицы, и у них есть VACUUM ANALYZE's. Все еще нет увеличения производительности. Я запускаю CENTOS 6 с Postgres 8.4 и PostGIS 1.5. Может ли кто-нибудь пролить свет на то, как ускорить процесс? Я получаю результаты очень быстро, ОГРАНИЧИВАЯ запрос до 1000 до 10000 записей. Когда я пытаюсь схватить полный набор результатов, он тащит. Мысли?

UPDATE: Теперь я вижу, что мне нужно уточнить свой запрос в качестве первого шага в этом процессе. Я получаю такой конверт

select astext(st_envelope(wkb_geometry)) as e 
from world_borders 
where cntry_name = 'UK' 

Теперь, что является самым эффективным способом включить/выполнить это как часть всего запроса?

+1

Каждый из последних выпусков улучшил индексы GiST и GIN. Возможно, вы захотите рассмотреть обновление до новой крупной версии. Возможно, даже стоит попробовать вашу проблему на бета-версии 9.2, поскольку она включает SP-GiST. http://www.postgresql.org/docs/9.2/static/spgist-intro.html – kgrittn

ответ

1

Попробуйте запустить EXPLAIN (и LIMIT), чтобы увидеть, используются ли индексы вообще.

Поскольку реальная проверка пересечения является самой медленной операцией там, возможно, она работает против подзапроса ST_Collect (все, кроме проверки ST_Intersects). Таким образом, будет только один вызов, и если конструкция многогеометрии будет достаточно быстрой, результат может быть лучше.

edit1: Ну, получается, что это не так оптимально, так как если вы не вынудит координаты 3d (для хранения и идентификатор), дополнительный поиск требуется, чтобы получить геометрическую ID:

SELECT d.id, d.geom 
FROM 
(
    SELECT * 
    FROM 
    ( 
     SELECT ST_Collect(d.geom) 
     FROM export d, world_boundaries b 
     WHERE (b.cntry_name = 'UK') 
     AND d.date_inserted >= '2012-06-01' 
     AND d.geom && b.wkb_geometry 
    ) as c, world_boundaries b 
    WHERE (b.cntry_name = 'UK') 
    AND ST_Intersection(c.geom, b.wkb_geometry); 
) as e, export d 
WHERE (ST_Dump(e.geom)).geom = d.geom 
+2

Не ожидайте, что план, сгенерированный с помощью LIMIT, обязательно будет похож на план без 'LIMIT'. Он * может * быть одним и тем же, но он может быть совершенно другим, поскольку планировщик будет искать самый дешевый план для возврата запрошенного количества строк, а самый дешевый план для возврата всех строк. Часто это различается. – kgrittn

+0

Любая возможность предоставить пример подзапроса ST_Collect(), например, с помощью инструкции SQL выше? – aeupinhere

+0

@kgrittn Конечно, но я очень сомневаюсь, что было бы дешевле не использовать индекс там, поэтому это должно быть хорошо, как диагностика для того, что я сказал. – lynxlynxlynx

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