0

我有一张桌子

foo(a1, a2, a3, a4, a5)

a1是主键。上有一个非聚集索引a5

我有一个简单的查询:

SELECT * 
FROM foo
WHERE a5/100 = 20;

此查询运行速度明显较慢。更新查询计划中使用的统计信息并没有太大帮助。

为什么会发生这种情况?我可能做错了什么?我是查询优化的新手。

4

2 回答 2

0

您正在 WHERE 谓词中的列上使用表达式,因此它不是 sargable(不能使用索引)。

这撇开了可能的基数问题,即数据分布 - 如果您的 WHERE 条件返回超过大约 40% 的行,则索引将变得无用。

编辑

在索引中搜索一个值,如果该值是表达式的结果,则不能使用索引。此外,诸如:NOT、NOT IN、<> 之类的运算符也是不可分割的,因为对于索引搜索,您需要一个明确的值(s) 因此优化器可以定义某种固定范围。随着您的动态计算,值会不断变化,因此您需要扫描整个表格。

于 2017-04-21T07:28:44.907 回答
0

您可以在表达式而不是基础数据上创建索引。如果你知道你总是将 a5 除以 100,你可以做一个索引:

CREATE INDEX ON foo ((a5/100));

额外的括号是必需的。

这样,任何查询都WHERE a5/100 = <something>将能够利用索引。

虽然它对WHERE a5/99 = <something>等没有帮助

https://www.postgresql.org/docs/current/static/indexes-expressional.html上的文档

于 2017-04-21T09:11:16.370 回答