Postgresql
為什麼 postgres 使用與查詢無關的奇數索引
(Debian 7,Postgres 9.3,具有巨大記憶體的專用機器)
我有一個名為 process_data (14gb) 的大表和另一個名為 process_location 的小查找表。我正在這兩者之間進行查詢,並且在解釋查詢中 Postgres 正在使用一個與查詢內容完全不相關的奇數索引,如下所示:
詢問:
select l.name, count(1) as quantity from process_data pd join process_location l on pd.fk_location = l.id_process_location where pd.active and pd.fk_status = 1 group by l.name order by l.name limit 1000
解釋查詢給了我這個:
+----------------------------------------------------------------------------------------------------------------------------------------------+ | QUERY PLAN | +----------------------------------------------------------------------------------------------------------------------------------------------+ | Limit (cost=166513.62..166513.88 rows=107 width=33) | | -> Sort (cost=166513.62..166513.88 rows=107 width=33) | | Sort Key: s.name | | -> HashAggregate (cost=166508.94..166510.01 rows=107 width=33) | | -> Hash Join (cost=4.84..165278.56 rows=246076 width=33) | | Hash Cond: (d.fk_location = s.id_process_location) | | -> Index Scan using idx_process_data_last_execution_start on process_data d (cost=0.43..161890.61 rows=246076 width=8) | | -> Hash (cost=3.07..3.07 rows=107 width=41) | | -> Seq Scan on process_location s (cost=0.00..3.07 rows=107 width=41) | +----------------------------------------------------------------------------------------------------------------------------------------------+
如我們所見,查詢使用索引 idx_process_data_last_execution_start,即:
"idx_process_data_last_execution_start" btree (priority, last_execution_start) WHERE fk_status = 1 AND active
查詢中沒有提到它的列,所以問題是:為什麼要使用它以及它有什麼幫助?
第二個問題是,為什麼它不使用我創建的這個索引:
"idx_process_data_fk_location_active_status_1" btree (fk_location) WHERE active AND fk_status = 1
這將更有意義,而且它的尺寸更小。奇數索引長 41mb,第二個索引長 30mb。
我正在努力理解索引是如何工作的。
沒有提到任何列
是的,他們是,就在這裡:
where pd.active and pd.fk_status = 1
匹配索引上的條件,因此索引可用於支持行的計數。讀取索引中的所有行應該比對
process_data
錶執行 seq 掃描更快。為什麼它不使用我無法分辨的其他索引。可能是因為大小的差異對於預期的行數並不重要(246076)
count(1)
順便說一句:和之間的性能絕對沒有區別count(*)
了解索引如何工作的一個非常好的網站是“使用索引,Luke”