如果存在多个索引,Postgres 如何选择使用哪个索引?
Posted
技术标签:
【中文标题】如果存在多个索引,Postgres 如何选择使用哪个索引?【英文标题】:How does Postgres choos which index to use in case if multiple indexes are present? 【发布时间】:2020-10-15 07:33:42 【问题描述】:我是 Postgres 的新手,如果我有多个如下定义的 btree 索引,我对 Postgres 如何决定使用哪个索引有点困惑。
CREATE INDEX index_1 ON sample_table USING btree (col1, col2, COALESCE(col3, 'col3'::text));
CREATE INDEX index_2 ON sample_table USING btree (col1, COALESCE(col3, 'col3'::text));
当我写入 sample_table(来自源表)时,我在联接条件中使用 col1, col2, COALESCE(col3, 'col3'::text) 但是当我进行解释分析以获取查询计划时,我有时会看到它使用 index_2 而不是 index_1 进行扫描,有时只使用顺序扫描。我想了解什么可以使 Postgres 使用一个索引而不是另一个索引?
【问题讨论】:
简而言之:优化器评估不同的策略并为每个策略分配一个成本值。然后选择成本最低的那个。有关更多说明,请参阅Using EXPLAIN 感谢@a_horse_with_no_name,您的解释 【参考方案1】:没有看到EXPLAIN (ANALYZE, BUFFERS)
的输出,我只能给出一个笼统的答案。
PostgreSQL 考虑所有可行的执行计划并估计每个节点的行数和成本。然后采用成本估算最低的方案。
可能是col2
上的条件有时更具选择性,有时则更少,例如因为您有时将其与稀有值进行比较,有时与频繁值进行比较。如果涉及col2
的条件不是选择性的,那么使用这两个索引中的哪一个并不重要。在这种情况下,PostgreSQL 更喜欢较小的两列索引。
【讨论】:
非常感谢@Laurenz Albe 的解释,关于同一行的另一个问题,postgres sql 是否可以强制/提示使用索引,如果可能的话,这样做是个好主意吗? 不,这是不可能的。只要查询有效执行,使用的索引应该无关紧要。考虑删除其中一项索引以获得更高的计划稳定性、更短的计划时间和更有效的数据修改。以上是关于如果存在多个索引,Postgres 如何选择使用哪个索引?的主要内容,如果未能解决你的问题,请参考以下文章
如何参数化 Postgres-custom-function 中的表和列,如果值存在则选择 PK,否则插入并返回 PK?