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

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 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

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

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
12天前
|
缓存 关系型数据库 MySQL
MySQL索引策略与查询性能调优实战
在实际应用中,需要根据具体的业务需求和查询模式,综合运用索引策略和查询性能调优方法,不断地测试和优化,以提高MySQL数据库的查询性能。
|
17天前
|
SQL 关系型数据库 MySQL
MySQL慢查询优化、索引优化、以及表等优化详解
本文详细介绍了MySQL优化方案,包括索引优化、SQL慢查询优化和数据库表优化,帮助提升数据库性能。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
MySQL慢查询优化、索引优化、以及表等优化详解
|
22天前
|
缓存 监控 关系型数据库
如何优化MySQL查询速度?
如何优化MySQL查询速度?【10月更文挑战第31天】
49 3
|
24天前
|
缓存 关系型数据库 MySQL
如何优化 MySQL 数据库的性能?
【10月更文挑战第28天】
48 1
|
2月前
|
NoSQL 关系型数据库 MySQL
MySQL与Redis协同作战:百万级数据统计优化实践
【10月更文挑战第21天】 在处理大规模数据集时,传统的单体数据库解决方案往往力不从心。MySQL和Redis的组合提供了一种高效的解决方案,通过将数据库操作与高速缓存相结合,可以显著提升数据处理的性能。本文将分享一次实际的优化案例,探讨如何利用MySQL和Redis共同实现百万级数据统计的优化。
77 9
|
26天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
139 1
|
2月前
|
NoSQL 关系型数据库 MySQL
MySQL与Redis协同作战:优化百万数据查询的实战经验
【10月更文挑战第13天】 在处理大规模数据集时,传统的关系型数据库如MySQL可能会遇到性能瓶颈。为了提升数据处理的效率,我们可以结合使用MySQL和Redis,利用两者的优势来优化数据查询。本文将分享一次实战经验,探讨如何通过MySQL与Redis的协同工作来优化百万级数据统计。
61 5
|
27天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第26天】数据库作为现代应用系统的核心组件,其性能优化至关重要。本文主要探讨MySQL的索引策略与查询性能调优。通过合理创建索引(如B-Tree、复合索引)和优化查询语句(如使用EXPLAIN、优化分页查询),可以显著提升数据库的响应速度和稳定性。实践中还需定期审查慢查询日志,持续优化性能。
57 0
|
17天前
|
SQL 关系型数据库 MySQL
12 PHP配置数据库MySQL
路老师分享了PHP操作MySQL数据库的方法,包括安装并连接MySQL服务器、选择数据库、执行SQL语句(如插入、更新、删除和查询),以及将结果集返回到数组。通过具体示例代码,详细介绍了每一步的操作流程,帮助读者快速入门PHP与MySQL的交互。
30 1
|
19天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
32 4