[英]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.