postgresql - 具有功能的部分索引不用于简单查询

标签 postgresql

此示例表有 5 亿行示例,包括 ID、名字、姓氏、电子邮件、电话号码。

我的索引创建:

CREATE INDEX ix_test_first_name_lower ON my_table(LOWER(first_name))
    WHERE first_name <> ''

我的简单查询:

SELECT id
FROM my_table
WHERE lower(first_name) = 'joe'

查询计划表明这个简单的查询正在对表进行顺序扫描并且没有使用我创建的索引。

为什么会这样?我不能在部分索引中使用函数吗?

编辑:

我注意到的最重要的部分。我在没有条件的情况下创建了我的索引,并注意到相同的查询然后使用了该索引。所以它看起来确实与索引中的 where 子句有关。

最佳答案

documentation说:

To be precise, a partial index can be used in a query only if the system can recognize that the WHERE condition of the query mathematically implies the predicate of the index. PostgreSQL does not have a sophisticated theorem prover that can recognize mathematically equivalent expressions that are written in different forms. (Not only is such a general theorem prover extremely difficult to create, it would probably be too slow to be of any real use.) The system can recognize simple inequality implications, for example “x < 1” implies “x < 2”; otherwise the predicate condition must exactly match part of the query's WHERE condition or the index will not be recognized as usable.

换句话说,Postgres 在识别何时可以使用部分索引方面并不聪明。您需要通过将索引谓词显式添加到查询来让它知道它可以在您的查询中使用索引:

SELECT id
FROM my_table
WHERE lower(first_name) = 'joe' AND first_name <> ''

关于postgresql - 具有功能的部分索引不用于简单查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58839486/

相关文章:

postgresql - 如何让子表的外键与父表的主自增键具有相同的值

postgresql - PostgreSql 中的临时文件

postgresql - 如何将 pgx.Rows 从 Query() 转换为 json 数组?

sql - 如何在 postgresql 或使用一些 sql 查询技巧中显示空结果集

ruby-on-rails - 为什么在尝试使用 postgresql 作为 RoR 中的数据库时会出现此错误?

sql - 我在哪里可以找到postgresql中的sql语句日志?

postgresql - 执行sql语法时出现异常

python - 使用 session.query 读取 SQLAlchemy 中未提交的数据

arrays - 将日期和整数合并到 ARRAY 中

postgresql - 使任何缓存失效(刷新)的合理时间间隔是多少?