Kev*_*Kev 7 postgresql performance index optimization postgresql-9.5 postgresql-performance
(这篇文章的后续内容:当我在子查询中 ORDER BY 时,为什么我的 PostgreSQL 表达式索引没有被使用?)
PostgreSQL 9.5。
我不能透露全部细节,但table有 22 列和 5 个索引:
text(btree)text(btree)timestamp with time zone(btree)tsvector(杜松子酒)bigint(btree)(从上一篇文章你知道我试图避免创建这个额外的列,只是使用表达式索引——将两integer列加在一起——没有成功。bigint这里的列可能只是“整数”,但我做了一个创建它时出错;添加列、填充它并重新编制索引花了大约一个小时,所以我希望这不相关,但要提及它以防万一。)
除了tsvector.
以下查询都只需要 12ms 并且只使用一个Index Scan:
SELECT pk FROM table ORDER BY pk DESC LIMIT 10SELECT pk FROM table ORDER BY text_column DESC LIMIT 10SELECT pk FROM table ORDER BY timestamp_column DESC LIMIT 10但是,如果我尝试将我的新bigint索引用于ORDER BY:
SELECT pk FROM table ORDER BY bigint_column DESC LIMIT 10
...它需要 2.7 秒并使用Limit -> Sort -> Seq Scan.
我的“作弊”方法是我似乎能够使用索引的最接近的方法:
SELECT pk
FROM table
WHERE bigint_column > 1000000
ORDER BY bigint_column DESC LIMIT 10
Run Code Online (Sandbox Code Playgroud)
这需要 12 毫秒并使用Limit -> Sort -> Bitmap Heap Scan (bigint_column > 1000000) -> Bitmap Index Scan (bigint_column > 1000000).
这是在VACUUM ANALYZE添加索引之后。
我觉得奇怪的是我的表达索引没有被用于另一个问题。现在它只是一个普通的旧专栏(我什至没有添加实际走这条路线的必要触发器。)
为什么我的最新索引没有被使用,而其他三个工作“很好”?(正如在https://dba.stackexchange.com/a/183290/28774的评论中指出的那样,仅索引扫描会更好。我不明白为什么所有这些查询都不会使用至少索引扫描,更不用说仅索引扫描,而不是完整的 Seq 扫描。)
索引定义具有DESC NULLS LAST(尽管它是不可为空的列。)
在 中PostgreSQL,DESC NULLS LAST不能使用is 的索引来满足ORDER BYis DESC NULLS FIRST(包括排序,DESC因为这意味着NULLS FIRST)。即使将列定义为NOT NULL.
您可以重建索引,或者(因为您知道该列不为空)您可以添加NULLS LAST到您的查询中ORDER BY以使其与现有索引匹配。
请注意,PostgreSQL它知道如何向后跟踪索引,因此默认索引(隐式ASC NULLS LAST)也能够满足您的DESC NULLS FIRST查询。因此,在索引中指定 DESC 很少很重要,但指定 NULLS 排序的终点可能很重要。