的排序是沒有問題的 - 事實上排序的CPU和內存的成本接近於零,因爲Postgres有頂-N排序,其中,同時保持最新一小類緩衝區只有抱着結果集進行掃描前N行。
select count(*) from (1 million row table) -- 0.17 s
select * from (1 million row table) order by x limit 10; -- 0.18 s
select * from (1 million row table) order by x; -- 1.80 s
所以你看到前10排序只增加了10毫秒到一個愚蠢的快速計數(*)與一個真正的排序更長的時間。這是一個非常整潔的功能,我使用它很多。現在沒有EXPLAIN
OK分析它不可能是肯定的,但我的感覺是,真正的問題是交叉連接。基本上你使用以下兩種表格過濾行:
where (A.power_peak between 1.0 AND 100.0)
and A.area_acre >= 500
and A.solar_avg >= 5.0
AND A.pc_num <= 1000
and (A.fips_level1 = '06' AND A.fips_country = 'US' AND A.fips_level2 = '025')
and B.volt_mn_kv >= 69
and B.fips_code like '%US06%'
and B.status = 'active'
好的。我不知道有多少行兩個表中選擇(只能解釋ANALYZE會告訴),但它可能顯著。知道這些數字會有所幫助。
然後,我們得到了最糟糕的情況下CROSS JOIN條件永遠
and ST_within(ST_Centroid(A.wkb_geometry), ST_Buffer((B.wkb_geometry), 1000))
這意味着A的所有行對B的所有行匹配(所以,這個表達式將被評估了大量的時間),使用了一堆非常複雜,慢速和cpu密集型功能。
當然,這是可怕的慢!
當您刪除ORDER BY,Postgres的只是上來(偶然?)帶着一幫在一開始的匹配行,它們輸出,並停止由於達到了極限。
這裏有一個小例子:
表A和B是相同的且包含1000行,和類型BOX的列。
select * from a cross join b where (a.b && b.b) --- 0.28 s
這裏百萬框重疊(操作者& &)測試在0.28s完成。測試數據集生成後,結果集只包含1000行。
create index a_b on a using gist(b);
create index b_b on a using gist(b);
select * from a cross join b where (a.b && b.b) --- 0.01 s
這裏索引用來優化交叉連接,速度很荒謬。
你需要以優化的幾何形狀匹配。
- 添加這將緩存列:
- ST_Buffer((B.wkb_geometry),1000)
- ST_Centroid(A.wkb_geometry)
有在重新計算NO POINT在CROSS JOIN期間,這些函數會慢一百萬次,所以將結果存儲在一列中。使用觸發器使其保持最新狀態。
也許你可以只指數ST_Centroid和ST_Buffer列...並使用(索引)「包含」操作符,在這裏看到:
http://www.postgresql.org/docs/8.2/static/functions-geometry.html
查詢返回多少行?在每種情況下通過EXPLAIN ANALYZE運行查詢時,輸出是什麼? – 2011-05-03 17:53:45
解決該問題的第一步是查看解釋分析*查詢的*兩個*版本的輸出。如果你不能閱讀它(它不是非常友好的),把它放在http://explain.depesz.com/並給我們兩個計劃的鏈接。 – 2011-05-03 18:10:17
該特定查詢的結果只有11行。 Explain Analyze的輸出沒有'order by'與WITH WITH的基本相同,減去排序行所用的117117 ms。 – 2011-05-03 18:21:48