[英]Extremely slow distinct query on indexed column
在Postgres數據庫中,我在一個有3億行的大表中查詢MY_DATE
不同值。 其中大約有400個並且MY_DATE
列被編入索引。
Select distinct MY_DATE from MY_TABLE;
查詢運行22分鍾 。
我的Oracle DB上具有完全相同的數據集和相同索引定義的相同查詢運行11秒。
查詢計划顯示查詢正在使用索引:
EXPLAIN Select distinct MY_DATE from MY_TABLE LIMIT 200;
得到:
QUERY PLAN
Limit (cost=0.57..7171644.14 rows=200 width=8)
-> Unique (cost=0.57..15419034.24 rows=430 width=8)
-> Index Only Scan using idx_obsdate on my_table (cost=0.57..14672064.14 rows=298788038 width=8)
當我限制結果時,查詢可以變得更快。 Ee.g.
Select distinct MY_DATE from MY_TABLE LIMIT 5;
在亞秒內運行。
但:
Select distinct MY_DATE from MY_TABLE LIMIT 50;
已經需要幾分鍾。 時間似乎隨着LIMIT
條款呈指數增長。
我希望Postgres查詢能在幾秒鍾內運行,就像我的OracleDB一樣。 索引掃描的20分鍾 - 即使對於大型桌子 - 似乎遠遠不夠。
是什么原因引起了這個問題以及我能做些什么?
不同的價值...... 3億行...大約400個......列...索引。
這有更快的技術。 模擬松散的索引掃描 (也就是跳過掃描),並假設my_date
被定義為NOT NULL
(或者我們可以忽略NULL值):
WITH RECURSIVE cte AS (
SELECT min(my_date) AS my_date
FROM my_table
UNION ALL
SELECT (SELECT my_date
FROM my_table
WHERE my_date > cte.my_date
ORDER BY my_date
LIMIT 1)
FROM cte
WHERE my_date IS NOT NULL
)
TABLE cte;
有關:
使用你提到的索引它應該以毫秒結束。
Oracle DB ... 11秒。
因為Oracle有本機索引跳過掃描而Postgres沒有。 正在努力在Postgres 12中實現類似的功能。
目前(Postgres 11),雖然索引用於良好的效果,即使在僅索引掃描中,Postgres也不能跳過,並且必須按順序讀取索引元組。 如果沒有LIMIT
,則必須掃描完整的索引。 因此我們在EXPLAIN
輸出中看到:
僅索引掃描... 行= 298788038
建議的新查詢在讀取400個索引元組(每個不同值一個)時實現相同。 很大的區別。
使用像您測試的LIMIT
(並且沒有ORDER BY
!),只要檢索到足夠的行,Postgres就會停止。 增加限制具有線性效應。 但是,如果每個不同值的行數可以變化,則增加的成本也會變化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.