此示例表有 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 子句有关。
最佳答案
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/