为什么不走索引, PostgreSQL

本文涉及的产品
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
简介: 我明明创建了索引字段,为什么不选择索引扫描呢?我该注意什么,怎么解决

原文出处:
">http://www.postgresonline.com/journal/archives/78-why-si-my-index-not-being-used.html>
有一个老的问题经常会问道数据库转件就是为什么或者为什么表的索引没有被使用?
下面的文章将会简单的回答这个常见的问题,并按着统计学意义排序。

一、对于外行人来说,你怎么知道索引没有被使用呢?
可以使用 EXPLAIN ; EXPLAIN ANALYZE 或者 pgadmin 的图形执行计划来查看。 ">http://www.postgresonline.com/journal/archives/27-Reading-PgAdmin-Graphical-Explain-Plans.html>
如果查询语句确实没有走索引,那么我们应该怎么做呢?

  1. 原因: 过时的统计信息。如果你的数据库 auto-vacuum 选项是打开的, 那么就不会引起这个问题的发生。但是如果你最近刚批量的导入数据,且新建了索引,那么很有可能,统计信息过期,导致查询优化器不能获得最新的统计信息,做出正确的判断。
    方案: vacuum analyze verbose sometable_name;

这里增加了 verbose 参数,是因为它可以使你看的更清晰 vacuum 是如何运作的。

  1. 原因: 查询优化器认为选择 table scan 要比选择 index scan 更快: 做出这种选择的原因是,查询涉及的表太小了, 或者我们构建索引的字段重复值太多。

    方案: 对于 布尔字段构建索引可以认为不是很重要,因为一半是数据,另一半也是数据。不过对这种字段构建部分索引是最好的选择,值索引活动的数据。
    
  2. 构建的索引与实际过滤字段的方式不兼容。这里有很多种解决方法
    3.1 LIKE %me 将永远不会选择索引扫描, 但是 LIKE me% 就有可能选择索引扫描

3.2 大小写的陷阱,例子如下

<pre><code>
 CREATE INDEX idx_faults_name ON faults USING btree (fault_name);     --- 构建的索引
 --- 查询语句如下
 SELECT * FROM faults WHERE UPPER(FAULT_NAME) LIKE 'CAR%' Possible fix;
--- 解决办法如下
 CREATE INDEX idx_faults_name ON faults  USING BTREE (upper(fault_name));
</code></pre>

3.3 这个问题很难被意识到, 通过阅读别人的问题,你就会更好的发现问题。这个问题涉及到了 运算符类

  <https://www.postgresql.org/message-id/49075E5E.6040701@gmail.com> 知道这个问题的解决方法的人很少


The other point is that in non-C locales, a standard varchar index isn't

usable for LIKE (the sort order is usually wrong). You can re-initdb
in C locale or create a varchar_pattern_ops index.
booktown=# create index first_name_idx_vpo on auth using btree

(first_name varchar_pattern_ops);

)
  解决方案如下:
  <pre><code>
  CREATE INDEX idx_faults_uname_varcahr_parttern on faluts USING BTREE (UPPER (fault_name) varchar_parttern_ops);
  </code></pre>
 看到这个解决方案,可能还需要下面的变体和 *IN* 子句才能解决问题。
 我们并不能证明这是数据库编码的问题, 数据的不同或者数据库版本的不同。 8。2 , 8.3 。 对于pg8.3 我们推荐使用 *UTF-8* 的编码方式初始化数据库。而对于 8.2 版本是使用的 *SQL-ASCII*, 这个参数 *varcahr_pattern_ops* 对于 *like* 语句是足够解决的。
  <pre><code>
  CREATE INDEX idx_faults_uname ON faults USING btree (upper (falut_name));

 SELECT fault_name from faults WHERE upper(fault_name) IN ( 'CASCADIA ABDUCTION', 'CABIN FEVER');
 </code></pre>
3.4  不兼容的数据类型。
       例如, 我们为日期类型构建索引,但是却通过将日期类型转换为 text 类型, 用在比较语句中, 是不选索引扫描的。
  1. 并不是所有的索引都会被使用。 尽管 pg8.1以上的版本开始支持 Bitmap Index scan. 该索引扫描允许一个表上构建多个索引, 在查询执行时,将这些索引构建为 内存位图的形式。 如果你构建了很多索引, 不要期望全部候选索引都会被用到。有些时候,执行 table scan 会更高效。

    1. 问题: 查询优化器的不完美。

      方案: 期待更美好的查询优化器的产生。 事实上, postgresql 优化器的能力很不错的。*If only I could provide hints, I could make this faster *.最好的解决方案就是让查询优化器变的更好。随着数据库的变化, 优化器也随之变化, 这就是数据库编程不同于其他编程的原因。
相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
3月前
|
监控 关系型数据库 数据库
PostgreSQL的索引优化策略?
【8月更文挑战第26天】PostgreSQL的索引优化策略?
94 1
|
3月前
|
SQL 关系型数据库 MySQL
SQL Server、MySQL、PostgreSQL:主流数据库SQL语法异同比较——深入探讨数据类型、分页查询、表创建与数据插入、函数和索引等关键语法差异,为跨数据库开发提供实用指导
【8月更文挑战第31天】SQL Server、MySQL和PostgreSQL是当今最流行的关系型数据库管理系统,均使用SQL作为查询语言,但在语法和功能实现上存在差异。本文将比较它们在数据类型、分页查询、创建和插入数据以及函数和索引等方面的异同,帮助开发者更好地理解和使用这些数据库。尽管它们共用SQL语言,但每个系统都有独特的语法规则,了解这些差异有助于提升开发效率和项目成功率。
371 0
|
3月前
|
关系型数据库 数据库 PostgreSQL
PostgreSQL索引维护看完这篇就够了
PostgreSQL索引维护看完这篇就够了
283 0
|
存储 关系型数据库 数据库
PostgreSQL技术大讲堂 - 第28讲:索引内部结构
从零开始学PostgreSQL技术大讲堂 - 第28讲:索引内部结构
730 2
|
关系型数据库 Go 数据库
《提高查询速度:PostgreSQL索引实用指南》
《提高查询速度:PostgreSQL索引实用指南》
586 0
|
关系型数据库 分布式数据库 数据库
PolarDB for PostgreSQL 14:全局索引
PolarDB for PostgreSQL 14 相较于 PostgreSQL 14,提供了更多企业级数据库的特性。本实验将体验其中的全局索引功能。
|
弹性计算 关系型数据库 OLAP
AnalyticDB PostgreSQL版向量索引查询
本案例对比了传统查询和使用向量索引执行查询的执行时间,助您体验使用向量索引查询带来的高效和快捷。
|
存储 SQL 关系型数据库
PostgreSQL插件HypoPG:支持虚拟索引
PostgreSQL插件HypoPG:支持虚拟索引
391 0
|
存储 缓存 关系型数据库
PostgreSQL 14新特性--减少索引膨胀
PostgreSQL 14新特性--减少索引膨胀
475 0
|
6月前
|
SQL 关系型数据库 数据库
RDS PostgreSQL索引推荐原理及最佳实践
前言很多开发人员都知道索引对于数据库的查询性能至关重要,一个好的索引能使数据库的性能提升成千上万倍。但给数据库加索引是一项相对专业的工作,需要对数据库的运行原理有一定了解。同时,加了索引有没有性能提升、性能提升了多少,这些都是加索引前就想知道的。这项繁杂的工作有没有更好的方案呢?有!就是今天重磅推出...
116 1
RDS PostgreSQL索引推荐原理及最佳实践