Postgresql

PostgreSQL 9.6 優化器使用索引,即使它較慢

  • January 20, 2017

我是索引和計劃的新手,所以我不得不尋求一些幫助。

我有一個表,我保留以下屬性:

id text NOT NULL 
t timestamp NOT NULL 
cost int NOT NULL

我對數據庫的查詢是:

SELECT AVG(cost)
FROM my_table
WHERE my_to_char(t) = 'Sunday   '
;

上述查詢的返回時間約為 4secs。

因此,為了提高查詢的性能,我在my_to_char(t).

但事實證明,這產生了相反的結果。查詢現在在 30 秒內返回。

但是,查詢計劃器選擇使用索引而不是進行順序掃描。

索引怎麼會比 seq scan 首先慢。有什麼解釋嗎?

也許是因為有太多行my_to_char(t) = 'Sunday '

編輯 - 查詢計劃

Aggregate  (cost=72841.43..72841.44 rows=1 width=32) (actual time=28383.473..28383.473 rows=1 loops=1)
Output: avg(cost)
->  Bitmap Heap Scan on my_table  (cost=900.60..72732.77 rows=43462 width=4) (actual time=120.778..28091.814 rows=1237954 loops=1)
Output: id, t, cost
Recheck Cond: (my_to_char(my_table.t) = 'Sunday   '::text)
Rows Removed by Index Recheck: 3053757
Heap Blocks: exact=33988 lossy=26432
->  Bitmap Index Scan on btree_date  (cost=0.00..889.74 rows=43462 width=0) (actual time=111.785..111.785 rows=1237954 loops=1)
Planning time: 0.270 ms
Execution time: 28384.284 ms

將表達式索引添加到表後,您需要手動 ANALYZE 表。否則 PostgreSQL 無權訪問它需要做出關於正確使用該索引的正確決策的數據。它必須進行瘋狂的猜測,顯然這些猜測在這種情況下很糟糕(它認為它會找到 43462 行,但實際上會找到 1237954)

也許添加表達式索引應該會自動觸發 ANALYZE 的發生——但目前它不能以這種方式工作。

引用自:https://dba.stackexchange.com/questions/160404