簡體   English   中英

索引列上極其緩慢的獨特查詢

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM