品易云推流 关闭
文章详情页
文章 > PostgreSQL > 为什么PostgreSQL查询很慢?为什么这些查询没有利用索引?

为什么PostgreSQL查询很慢?为什么这些查询没有利用索引?

postgresql 数据库 索引

头像

2021-01-23 16:06:446063浏览 · 0收藏 · 0评论

banner51.png

并非每个PostgreSQL查询都会自动使用索引,只有在表的大小超过一个最小值,并且查询只会选中表中较小比例的记录时才会采用索引。这是因为索引扫描引起的随即磁盘存取可能比直接地读取表(顺序扫描)更慢。

为了判断是否使用索引,PostgreSQL必须获得有关表的统计值。这些统计值可以使用 VACUUM ANALYZE,或 ANALYZE 获得。 使用统计值,优化器知道表中有多少行,就能够更好地判断是否利用索引。 统计值对确定优化的连接顺序和连接方法也很有用。在表的内容发生变化时,应定期进行统计值的更新收集。
索引通常不用于 ORDER BY 或执行连接。对一个大表的一次顺序扫描,再做一个显式的排序通常比索引扫描要快。
但是,在 LIMIT 和 ORDER BY 结合使用时经常会使用索引,因为这只会返回表的一小部分。 实际上,虽然 MAX() 和 MIN() 并不使用索引,通过对 ORDER BY 和 LLIMIT 使用索引取得值和最小值也是可以的:
SELECT colFROM tabORDER BY col [ DESC ]LIMIT 1;
如果你确信PostgreSQL的优化器使用顺序扫描是不正确的,你可以使用SET enable_seqscan TO 'off' 然后再次运行查询,你就可以看出使用一个索引扫描是否确实要快一些。当使用通配符操作,例如 LIKE 或 ~ 时,索引只能在特定的情况下使用。
比如字符串的开始部分必须是普通字符串,也就是LIKE模式不能以 % 打头。~(正则表达式)模式必须以 ^ 打头。
字符串不能以匹配多个字符的模式类打头,例如 [a-e]。
大小写无关的查找,如ILIKE和 ~* 等不使用索引。
在做 initdb 时必须采用缺省的本地设置Clocale,因为系统不可能知道在非C locale情况时下一个字符是什么。在这种情况下,你可以创建一个特殊的text_pattern_ops索引来用于LIKE的索引。

关注

关注公众号,随时随地在线学习

本教程部分素材来源于网络,版权问题联系站长!

底部广告图