浅谈MySQL原理与优化(三)—— 索引

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 索引是数据库中的一种非常重要的存储结构。优秀的索引对于数据库性能有着很大的提升。本文解析了MySQL索引的原理,并给出了一些索引的设计原则

索引是数据库中的一种非常重要的存储结构。优秀的索引对于数据库性能有着很大的提升。索引的英文是index。这个词最早的含义是书的目录。类似于下图的样子。

image.png

一本书有很多页,当我们想找一个内容的时候其实是很费时费力的,但是当我们有了索引目录以后,通过每一条索引记录中关键词和页码的对应关系,我们就可以更快的找到想要的内容。

image.png

为了加快查找速度,索引记录一定是按关键词顺序排列的,而且我们还可以建立类似下图的多级目录的结构,第一级用来索引关键词首字母,这样可以让我们快速的跳过无关的目录内容,进一步提升查找的性能。

数据库索引的作用也是类似的,本质是建立了一个数据库表中字段的值和数据存储位置的对应关系。同样,为了加速查找速度,索引记录也是按照值的顺序来排列,并且有多个层级。这个数据结构一般被实现为B+树。

image.png

最终每一条记录会指向数据的”存储位置”(这个位置是广义上的,对于不同的存储引擎,位置的实现不同)

那么我们怎么样建立数据库索引才能产生更好的性能呢。我们注意要满足以下的原则:

1. 索引要有区分度

好的索引是能够把数据均匀的分成尽可能多的子群。类似于性别这样的字段其实非常不适合做索引。因为只能把人群分成两部分,最多只能过滤一半人。考虑一下省份这个字段,如果有确定的值,可以过滤掉 95%以上的人。但是省份字段并非完美,因为每个省的人数可能不一样,有些省的人口可能人数很多,这样的的话有些情况下可能只能过滤掉90%的人,区分度有些损失。

2. 索引要有确定的值,NULL无法被索引

根据SQL标准,NULL值和其他值的比较是无法确定的。大部分情况下,NULL值无法被索引。即便SQL语句中用到了IS NULL的条件,也无法用到索引。所以如果字段中空值太多就不适合作为索引。如果一定要索引空值,可以考虑给空值一个特殊的确定值。但是仍然要考虑空值占比

3. 索引会影响更新,非越多越好

由于索引是根据数据字段的值进行排列的数据结构,数据值的修改会导致索引的更新,会有一定的性能开销,索引加的越多,性能开销越大。

4. 多个字段可以组成复合索引,但是在MySQL中要满足最左前缀匹配。

可以为多个字段建立同一个索引,索引记录中会按照这两个字段拼接起来排序。所以查询要满足最左前缀匹配,也就是说复合索引(a,b,c)可以对a=1 and b=2 and c =3和a=1 and b =2 和 a=1 这样的条件生效,但是对于 b=2 and c=3,b=2 或者c=3 这类的条件无法发挥作用。

5. 避免在字段上使用子查询

如果在字段上使用子查询的话是无法使用索引的,比如下面这一句并不能用到actor_id这个索引。
image.png

你也许会觉得Mysql会先执行in里的子查询,再使用actor_id的索引,实际上并不是这样。Mysql会对每一个actor_id执行一遍子查询,性能会比较差

如果将其改写成Join则性能会提升很多。

image.png

6. 避免在字段上使用函数

在字段上使用函数再做比较的话,是无法用到索引的,因为索引只记录了原始的值和数据位置的对应关系,并没有记录函数处理后的值。如果一定要用函数,一种处理是在数据库中直接存储函数处理以后的值,并建立索引。另一种办法是使用特殊的函数索引(需要更高的mysql版本)
image.png

希望以上的内容,对大家的日常工作能起到帮助。

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
18天前
|
SQL 存储 关系型数据库
MySQL秘籍之索引与查询优化实战指南
最左前缀原则。不冗余原则。最大选择性原则。所谓前缀索引,说白了就是对文本的前几个字符建立索引(具体是几个字符在建立索引时去指定),比如以产品名称的前 10 位来建索引,这样建立起来的索引更小,查询效率更快!
82 22
 MySQL秘籍之索引与查询优化实战指南
|
18天前
|
SQL 关系型数据库 MySQL
MySQL事务日志-Undo Log工作原理分析
事务的持久性是交由Redo Log来保证,原子性则是交由Undo Log来保证。如果事务中的SQL执行到一半出现错误,需要把前面已经执行过的SQL撤销以达到原子性的目的,这个过程也叫做"回滚",所以Undo Log也叫回滚日志。
MySQL事务日志-Undo Log工作原理分析
|
1天前
|
存储 关系型数据库 MySQL
浅入浅出——MySQL索引
本文介绍了数据库索引的概念和各种索引结构,如哈希表、B+树、InnoDB引擎的索引运作原理等。还分享了覆盖索引、联合索引、最左前缀原则等优化技巧,以及如何避免索引误用,提高数据库性能。
|
14天前
|
SQL 关系型数据库 MySQL
MySQL派生表合并优化的原理和实现
通过本文的详细介绍,希望能帮助您理解和实现MySQL中派生表合并优化,提高数据库查询性能。
52 16
|
15天前
|
SQL 关系型数据库 MySQL
MySQL派生表合并优化的原理和实现
通过本文的详细介绍,希望能帮助您理解和实现MySQL中派生表合并优化,提高数据库查询性能。
33 7
|
13天前
|
SQL 存储 关系型数据库
MySQL进阶突击系列(05)突击MVCC核心原理 | 左右护法ReadView视图和undoLog版本链强强联合
2024年小结:感谢阿里云开发者社区每月的分享交流活动,支持持续学习和进步。过去五个月投稿29篇,其中17篇获高分认可。本文详细介绍了MySQL InnoDB存储引擎的MVCC机制,包括数据版本链、readView视图及解决脏读、不可重复读、幻读问题的demo演示。
|
19天前
|
存储 关系型数据库 MySQL
MySQL中为什么要使用索引合并(Index Merge)?
通过这些内容的详细介绍和实际案例分析,希望能帮助您深入理解索引合并及其在MySQL中的
76 10
|
2天前
|
缓存 关系型数据库 MySQL
【深入了解MySQL】优化查询性能与数据库设计的深度总结
本文详细介绍了MySQL查询优化和数据库设计技巧,涵盖基础优化、高级技巧及性能监控。
28 0
|
29天前
|
存储 Oracle 关系型数据库
数据库传奇:MySQL创世之父的两千金My、Maria
《数据库传奇:MySQL创世之父的两千金My、Maria》介绍了MySQL的发展历程及其分支MariaDB。MySQL由Michael Widenius等人于1994年创建,现归Oracle所有,广泛应用于阿里巴巴、腾讯等企业。2009年,Widenius因担心Oracle收购影响MySQL的开源性,创建了MariaDB,提供额外功能和改进。维基百科、Google等已逐步替换为MariaDB,以确保更好的性能和社区支持。掌握MariaDB作为备用方案,对未来发展至关重要。
59 3
|
29天前
|
安全 关系型数据库 MySQL
MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!
《MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!》介绍了MySQL中的三种关键日志:二进制日志(Binary Log)、重做日志(Redo Log)和撤销日志(Undo Log)。这些日志确保了数据库的ACID特性,即原子性、一致性、隔离性和持久性。Redo Log记录数据页的物理修改,保证事务持久性;Undo Log记录事务的逆操作,支持回滚和多版本并发控制(MVCC)。文章还详细对比了InnoDB和MyISAM存储引擎在事务支持、锁定机制、并发性等方面的差异,强调了InnoDB在高并发和事务处理中的优势。通过这些机制,MySQL能够在事务执行、崩溃和恢复过程中保持
71 3