2012-07-01 181 views
5

我有兩個表,我想要相交。第一張表格大約有5000萬分,第二張表是世界上所有國家的多邊形層。我想獲得與該多邊形相交的所有點。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。仍然沒有性能提高。我使用Postgres 8.4和PostGIS 1.5運行CENTOS 6。任何人都可以點亮如何加快速度?將查詢限制爲1000到10000條記錄時,我可以非常快速地得到結果。當我嘗試抓取完整的結果集時,它會拖動。思考?

更新:我現在看到,我必須優化我的查詢,作爲此過程中的第一步。我得到這樣

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

現在的信封,什麼是最有效的方式,包括/執行這是全體查詢的一部分?

+1

最近的每個版本都改進了GiST和GIN索引。您可能需要考慮升級到新的主要版本。它甚至可能值得在9.2 beta版本上嘗試你的問題,因爲它包含了SP-GiST。 http://www.postgresql.org/docs/9.2/static/spgist-intro.html – kgrittn

回答

1

嘗試使用EXPLAIN(和LIMIT)運行它以查看是否正在使用索引。

由於真正的交集檢查是那裏最慢的操作,可能在子查詢的ST_Collect上運行它(除了ST_Intersects檢查之外的任何事情)都會有所幫助。那樣只會有一個呼叫,如果多重幾何結構足夠快,最終的結果可能會更好。

EDIT1: 嗯,原來也不是那麼最優的,因爲除非你強制座標3D(也持有ID),需要一個額外的查找來獲得幾何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

像上面的SQL語句一樣提供ST_Collect()子查詢的例子嗎? – aeupinhere

+0

@kgrittn當然,但我非常懷疑不使用索引會更便宜,所以它應該很好,作爲我所說的診斷。 – lynxlynxlynx