[英]Why is PostgreSQL 11 optimizer refusing best plan which would use an index w/ included column?
PostgreSQL 11 不夠聰明,無法使用包含列的索引?
CREATE INDEX organization_locations__org_id_is_headquarters__inc_location_id_ix
ON organization_locations(org_id, is_headquarters) INCLUDE (location_id);
ANALYZE organization_locations;
ANALYZE organizations;
EXPLAIN VERBOSE
SELECT location_id
FROM organization_locations ol
WHERE org_id = (SELECT id FROM organizations WHERE code = 'akron')
AND is_headquarters = 1;
QUERY PLAN
Seq Scan on organization_locations ol (cost=8.44..14.61 rows=1 width=4)
Output: ol.location_id
Filter: ((ol.org_id = $0) AND (ol.is_headquarters = 1))
InitPlan 1 (returns $0)
-> Index Scan using organizations__code_ux on organizations (cost=0.42..8.44 rows=1 width=4)
Output: organizations.id
Index Cond: ((organizations.code)::text = 'akron'::text)
organization_locations 目前只有 211 行,平均行長 91 字節。
我只加載一個數據頁。 但是獲取索引頁的 I/O 相同,並且目標數據就在那里(無需從索引中額外查找數據頁)。 PG對這個計划有什么想法?
這只是為我創建了一個待辦事項,以便我回過頭來檢查以確保一旦表格迅速發展就開始生成正確的計划。
編輯:這是緩沖區的解釋:
Seq Scan on organization_locations ol (cost=8.44..14.33 rows=1 width=4) (actual time=0.018..0.032 rows=1 loops=1)
Filter: ((org_id = $0) AND (is_headquarters = 1))
Rows Removed by Filter: 210
Buffers: shared hit=7
InitPlan 1 (returns $0)
-> Index Scan using organizations__code_ux on organizations (cost=0.42..8.44 rows=1 width=4) (actual time=0.008..0.009 rows=1 loops=1)
Index Cond: ((code)::text = 'akron'::text)
Buffers: shared hit=4
Planning Time: 0.402 ms
Execution Time: 0.048 ms
讀取一個索引頁並不比讀取一個表頁便宜,因此對於小型表,您不能指望從僅索引掃描中獲得收益。
另外,你有沒有
VACUUM organization_locations;
沒有它,可見性 map 不會顯示表塊是全可見的,因此無論如何您都無法獲得僅索引掃描。
除了其他答案之外,這可能是一個愚蠢的索引。 當您需要唯一索引但您還想添加不屬於唯一約束的列時,或者當包含的列沒有 btree 運算符因此不能在主體中時,INCLUDE 很好指數。 在其他情況下,您應該只將額外的列放在索引本身中。
這只是為我創建了一個待辦事項,以便我回過頭來檢查以確保一旦表格迅速發展就開始生成正確的計划。
這是您不能指望 PostgreSQL 為您解決的工作流程問題。 您真的認為 PostgreSQL 應該根據想象的場景制定實際計划嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.