2015-08-19 79 views
1

我有一個28列和7M記錄沒有主鍵的表。爲什麼此查詢在PostgreSQL中不使用僅索引掃描?

CREATE TABLE records (
    direction smallint, 
    exporters_id integer, 
    time_stamp integer 
    ... 
) 

我在此表和真空表建立索引後(自動清理是)

CREATE INDEX exporter_dir_time_only_index ON sacopre_records 
USING btree (exporters_id, direction, time_stamp); 

,我想執行這個查詢

SELECT count(exporters_id) FROM records WHERE exporters_id = 50 

表有6982224條記錄與exporters_id = 50.我希望這個查詢使用僅索引掃描來獲得結果,但它使用順序掃描。 這是 「EXPLAIN ANALYZE」 輸出:

Aggregate (cost=204562.25..204562.26 rows=1 width=4) (actual time=1521.862..1521.862 rows=1 loops=1) 
-> Seq Scan on sacopre_records (cost=0.00..187106.88 rows=6982149 width=4) (actual time=0.885..1216.211 rows=6982224 loops=1) 
    Filter: (exporters_id = 50) 
    Rows Removed by Filter: 2663 
Total runtime: 1521.886 ms 

但是當我改變exporters_id到另一個ID,查詢使用僅索引掃描

Aggregate (cost=46.05..46.06 rows=1 width=4) (actual time=0.321..0.321 rows=1 loops=1) 
-> Index Only Scan using exporter_dir_time_only_index on sacopre_records (cost=0.43..42.85 rows=1281 width=4) (actual time=0.313..0.315 rows=4 loops=1) 
    Index Cond: (exporters_id = 47) 
    Heap Fetches: 0 
Total runtime: 0.358 ms 

問題出在哪裏?

+0

你試過了'SELECT COUNT(exporters_id = 50)FROM records'? – Tordek

+0

@Tordek,我現在測試它並得到相同的結果,它使用seq-scan。 –

+0

也許新的索引不分析,因此提交給策劃者?..嘗試'真空分析記錄' –

回答

3

解釋告訴你原因。仔細觀察。

Aggregate (cost=204562.25..204562.26 rows=1 width=4) (actual time=1521.862..1521.862 rows=1 loops=1) 
-> Seq Scan on sacopre_records (cost=0.00..187106.88 rows=6982149 width=4) (actual time=0.885..1216.211 rows=6982224 loops=1) 
    Filter: (exporters_id = 50) 
    Rows Removed by Filter: 2663 
Total runtime: 1521.886 ms 

你的過濾器在表中刪除僅2663排出來的6982149行的總金額,因此做了順序掃描確實應該比使用一個索引速度更快,因爲磁盤頭應該通過6982149 - 2663無論如何都是= 6979486記錄。磁頭開始順序讀取整個表格,並且正在移除那些與您的標準不符的小部分(0.000004%)。在索引掃描的情況下,它應該從索引文件跳轉到數據文件6979486次,肯定應該比現在得到的1.5秒慢!

+0

只是注意到相同的 –

+1

「並回到數據文件」......但他們正在做一個「COUNT」,通過索引字段,肯定引擎可以只遍歷索引並忽略數據? – Tordek

+0

我同意@Tordek,這是沒有必要回到數據文件! –

相關問題