Postgresql

為什麼 postgres 使用與查詢無關的奇數索引

  • November 11, 2014

(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”

http://use-the-index-luke.com/

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