数据库索引,真的越建越好吗?(中)

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介: 索引是提高关系型数据库查询性能的利器,但其并非银弹,必须精通其原理,才能发挥奇效。

回表

二级索引不保存原始数据,通过索引找到主键后需要再查询聚簇索引,才能拿到想要的数据。

示例如下:

image.png

key=person_name_score_index,表明走的是person_name_score_index索引。

type=ref,表明是二级索引的等值匹配,符合预期

再看如下SQL的执行计划:

image.png

Extra列多了一行Using index,说明直接查的二级索引,没有回表。

联合索引保存了多个索引列的值,对于页中的记录先按照字段1排序,若相同再按照字段2排序,如下:

image.png

图中叶子节点每一条记录的第1、2个方块是索引列的数据,第三个方块是记录的主键。若查询的是索引列索引或联合索引能覆盖的数据,则查询索引本身已经“覆盖”了需要的数据,无需再回表。这种情况也叫索引覆盖

索引开销的最佳实践

  • 无需一开始就建立索引,可等到场景明确或数据量超过1w、查询变慢,再针对需要查询、排序或分组的字段创建索引。创建索引后可使用EXPLAIN确认查询是否可以使用索引。
  • 尽量索引轻量级的字段,比如能索引int字段就不要索引varchar字段。索引字段也可以是部分前缀,在创建的时候指定字段索引长度。针对长文本的搜索,可以考虑使用Elasticsearch等专门用于文本搜索的索引数据库
  • 禁止SELECT *,而是SELECT必须字段,甚至可以考虑使用联合索引包含我们要搜索的字段,既能实现索引加速,又可避免回表。

不是所有针对索引列的查询都能用上索引

  • 是不是建了索引一定可以用上?
  • 到底是创建联合索引还是多个独立索引?

索引失效场景

索引只能匹配列前缀

LIKE语句查询name后缀为name123的用户,type=ALL全表扫描

image.png

把百分号放到后面走前缀匹配:

  • type=range索引扫描
  • key=person_name_score_index走person_name_score_index索引
  • image.png
  • 索引中行数据按索引值排序,只能根据前缀进行比较。

若非要按后缀查询也能走索引,并且永远只是按后缀查询,可以把数据反过来存,用时再倒过来。

条件涉及函数操作无法走索引

比如查询条件用到了LENGTH函数,肯定无法走索引,type=ALL全表扫描

image.png

同理,索引保存的是索引列的原始值,而非经过函数计算后的值。若需要针对函数调用还能走索引,只能保存一份函数变换后的值,然后重新针对这个计算列做索引。

联合索引只能匹配左边的列

虽然对name和score建了联合索引,但仅按score列查询无法走索引

image.png

因为在联合索引情况下,数据按照索引第一列排序,第一列数据相同时才会按第二列排序。若想使用联合索引中尽可能多的列,查询条件中的各个列必须是联合索引中从最左边开始连续的列。若仅按第二列搜索,肯定无法走索引。


尝试把查询条件加入name列,可见走了person_name_score_index索引

image.png

因为有查询优化器,所以name作为WHERE子句的第几个条件并不重要。

现在回答一开始的问题:

  • 是不是建了索引一定可以用上?
    并不,只有当查询能符合索引存储的实际结构时,才能用上。刚才几个示例都用不上索引。
  • 联合索引 or 多个独立索引?
    若你的查询条件经常会使用多个字段,则考虑针对这几个字段建联合索引;同时,针对多字段建立联合索引,使用索引覆盖的可能更大。若只会查询单个字段,考虑建单独的索引,毕竟联合索引保存了不必要字段也有成本。

数据库基于成本决定是否走索引

查询数据可直接在聚簇索引上进行全表扫描,也可走二级索引扫描后到聚簇索引回表。

MySQL如何确定走哪个方案?

MySQL在查询数据之前,会先对可能的方案做执行计划,然后依据成本决定走哪个执行计划。

包括IO成本和CPU成本:

  • I/O成本
    从磁盘把数据加载到内存的成本。默认情况下,读取数据页的I/O成本常数是1(即读取1个页成本是1)。
  • CPU成本
    检测数据是否满足条件和排序等CPU操作的成本。默认情况下,检测记录的成本是0.2。

全表扫描成本

全表扫描,就是把聚簇索引中的记录依次和给定的查询条件对比,把符合搜索条件的记录加入结果集的过程。

所以要计算全表扫描的代价需要两个信息:

  • 聚簇索引占用的页面数,用来计算读取数据的IO成本
  • 表中的记录数,用来计算搜索的CPU成本

MySQL是实时统计的这些信息吗?

不是的,MySQL维护了表的统计信息,可使用命令:

7.png

可见总行数100147行。里表不是只有10w行记录吗,为啥这里还多了147行?

因为MySQL的统计信息只是个估算。现在我们估算下CPU成本:

100147*0.2=20030

数据长度是5783552B。对于InnoDB,这就是聚簇索引占用空间,等于聚簇索引的页面数量 * 每个页面的大小。InnoDB每个页16K,大概计算出页面数量是353,所以I/O成本是353。


综上,全表扫描总成本约20383。




相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
26天前
|
存储 关系型数据库 MySQL
索引大战:探秘InnoDB数据库中B树和Hash索引的优劣
索引大战:探秘InnoDB数据库中B树和Hash索引的优劣
17 0
|
28天前
|
数据库 索引
数据库索引的作用和优点缺点
数据库索引的作用和优点缺点
15 1
|
2月前
|
存储 搜索推荐 关系型数据库
深度探讨数据库索引的数据结构及优化策略
深度探讨数据库索引的数据结构及优化策略
|
2月前
|
存储 关系型数据库 MySQL
最全MySQL面试60题(含答案):存储引擎+数据库锁+索引+SQL优化等
最全MySQL面试60题(含答案):存储引擎+数据库锁+索引+SQL优化等
200 0
|
26天前
|
SQL 数据库 数据库管理
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(一)模式、表、索引与视图
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(一)模式、表、索引与视图
59 11
|
7天前
|
存储 机器学习/深度学习 搜索推荐
深入解析矢量数据库的数据模型与索引机制
【4月更文挑战第30天】本文深入探讨了矢量数据库的数据模型和索引机制。向量数据库以高维向量表示数据,采用稀疏或密集向量形式,并通过数据编码和组织优化存储与检索。索引机制包括基于树的(如KD-Tree和Ball Tree)、基于哈希的(LSH)和近似方法(PQ),加速相似性搜索。理解这些原理有助于利用矢量数据库处理大规模高维数据,应用于推荐系统、图像搜索等领域。随着技术发展,矢量数据库将扮演更重要角色。
|
8天前
|
关系型数据库 数据库 索引
关系型数据库使用索引
关系型数据库使用索引
22 1
|
9天前
|
关系型数据库 大数据 数据库
关系型数据库索引优化
关系型数据库索引优化是一个综合的过程,需要综合考虑数据的特点、查询的需求以及系统的性能要求。通过合理的索引策略和技术,可以显著提高数据库的查询性能和整体效率。
18 4
|
10天前
|
数据库 UED 索引
构建高效的数据库索引:提升查询性能的关键技巧
本文将深入探讨数据库索引的设计和优化,介绍如何构建高效的数据库索引以提升查询性能。通过学习本文,读者将掌握数据库索引的原理、常见类型以及优化策略,从而在实际应用中提升数据库查询效率。
|
11天前
|
关系型数据库 MySQL 数据库
【MySQL】数据库索引(简单明了)
【MySQL】数据库索引(简单明了)