Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >MySQL索引使用规则总结

MySQL索引使用规则总结

原创
作者头像
一生何求
修改于 2019-07-22 04:11:53
修改于 2019-07-22 04:11:53
4K1
举报
文章被收录于专栏:短信防刷短信防刷

如何加快查询,最直接有效的办法就是增加索引,在不使用索引的情况下试图采用其他方式加快查询就是在浪费时间。本文先介绍下MySQL索引的基本数据结构,再对索引的基本规则做下总结。

索引的必要性

通过索引查找的整体思路是避免遍历查找,而是通过已经建立好的索引结构找到目标数据, 或确认目标数据不存在,从而完成查询。如果说在单表不用索引的情况下遍历查询还可以忍受,那么在多表联合查询的情况下不使用索引时匹配次数将会达到天文数字。

再重温下这个常见的例子:3个没有索引的表table1,table2,table3。每个数据表都包含一个数据列c1,c2,c3,且每个数据列都从数字1到数字1000的1000个数据行。要查找这些数据表中具有相同数值的所有数据行的组合,其查询语句应该是下面这样:

select table1.c1,table2.c2,table3.c3 from table1 inner join table2 inner join table3 where table1.c1 = table2.c2 and table2.c2 = table3.c3

在不是用索引的情况下遍历查询需要从(1000*1000*1000) = 10亿的临时记录中匹配出实际需要的1000条数据,显然造成了极大的浪费。

在使用索引情况下来分析下关联查询的过程:

  • 从数据表table1中选择第一个数据行,看这个数据行包含什么样的值
  • 对数据表table2中使用索引,直接找到与数据表table1的值相匹的数据行。同样,对数据表table3使用索引,直接找到与数据表table1的值相匹配的数据行
  • 对数据表table1的下一个数据行重复上面的过程, 直到检查完数据表table1的所有数据行。

整个查询过程中table1遍历查询,但table2,table3都是带索引搜寻,直接将那些数据挑选出来,查询速度比不用索引时快了100万倍。

MySQL索引实现

MyISAM索引实现

  1. 数据与索引是分开存放(图一);
  2. 新增数据直接追加写数据文件,同时更新索引;
  3. B+树的叶子节点上存储的是数据的实际地址偏移;
  4. 主索引与辅助索引(图二)在数据结构上没有区别。主Key可以等同唯一索引。

(图一)

(图二)

MyISAM按主Key范围查找的时候仍然可能会导致随机读取,这对机械磁盘来说是个悲剧。

InnoDB索引实现

  1. 数据文件是按B+树组织的一个索引结构文件(图三),这个数据文件的索引就是主Key。
  2. 这棵B+树的叶节点data域保存了完整的数据记录。InnoDB的辅助索引(图四)data域存储相应记录主键的值而不是数据地址。
  3. 如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。

(图三)

(图四)

索引常用使用方式

  • 在查询操作中把与where子句所给出的条件相匹配的数据行尽快找出;
  • join等关联操作中把与其他行相关的数据行尽快找出来;
  • min(),max()函数操作的列如果是建立索引的,那么min,max求值时可以迅速找到而不用通过逐行遍历的方式查找;
  • 如果某些列经常需要order by, group by的列加上索引也可以加快排序和分类操作;

挑选合适的列作索引

1.经常出现在where、group by, order by,join子句后的列考虑建立索引。

2.建立的索引列需要有较好区分度。如果数据列的独一无二的值越多,区分度越高,索引效果越好。例如:对班级表格的性别字段的索引只有两个值’F’,’M’,采用性别别的索引无论怎么查询,得到的是数据表的一半左右的记录。MySQL的查询优化逻辑甚至不会选择对于这样的索引,而改成遍历搜索。

3.数据列尽量的短小。例如能用整型的就不要用字符串类型。

原因:短小数值可以让比较操作更快完成,加快查找速度;短小数值可以让索引体积更小,减少磁盘I/O;短小数值可以让缓存里容纳更多的索引信息。InnoDB存储引擎短小的主Key有助于减少辅助索引的体积;

4.为字符串的前缀设置索引。例如某列char(100),但大多数前10或20已经有足够的区分度就没必要为整个字符串列建立索引。原因还是出于磁盘I/O,缓存空间,匹配效率方面考虑。

5.在InnoDB中要用单调字段作为主键。原因:InnoDB数据文件本身是一颗B+Tree,非单调的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效,而使用自增字段作为主键则是一个很好的选择。

使用索引的基本原则

1.数据类型相同的数据列进行比较;例如int/init比较,bigint/bigint比较效率就要好于int/bitint的比较

2.带索引的数据列在比较表达式中单独出现;例如

where mycol*2 < 4;数据列中每一个值都要被读取并计算结果在比较

where mycol < 4/2;优化程序先计算表达式4/2,然后在索引里进行检索

3.复合索引充分利用最左前缀。创建了N个列的符合索引,实际上创建了MySQL能够使用的n个索引。例如某表的复合索引 index(国家,省份,城市)。那么可用索引为

A.国家

B.国家,省份

C.国家,省份,城市

但必须满足最左缀原理。如果查询条件里只有国家,城市就无法充分利用改符合索引。

4.不在like的开始部分使用通配符。例如:

where col_name like ‘%string%’;如果是要查询出现在数据列的字符串,这子句是正确的,此时并没有使用col_name的索引,但不要出于习惯将%放到string两侧。如果改成

Where col_name like ‘string%’查询依string开头的字符串就可以使用col_name上的索引

5.自动类型转换可能会阻止索引的使用;例如:

select * from mytbl where num_col = 4;

select* from mytbl where num_col = ‘4’;

如果num_col是int且有索引,那么第二条语句有可能会阻止索引使用。

6.验证各种查询优化时需要变化查询参数多次运行。有时会发现当运行一种查询优化时查速度慢,当换另外一种查询方式时速度变快,此时会觉得第二种查询方式的效果更好。然后再用第一种查询方式查询发现速度通用变快。实际上这只不过是第一次查询时的信息仍然保存再缓存内,当后续查询时发现查询速度变快

过多索引带来的问题

  1. 过多索引影响写性能。写操作时索引需要根据写入的数据进行调整,这样会降低带索引数据列的插入,删除,修改的速度。一个数据表的索引越多,需要做的调整调整越多,平均写性能降低的就越多。
  2. 过多索引需要消耗更多的磁盘空间。索引在本质上通过空间换取时间。所以:谨慎创建索引,尽量采用已有索引,不需要的索引不要创建。

参考:

1、MySQL技术内幕:InnoDB存储引擎 2、MySQL技术内幕:第4版 3、MySQL高效编程 4、MySQL的官方手册 5、http://km.oa.com/articles/show/190056?kmref=search&from_page=1&no=1

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
1 条评论
热度
最新
已关注,欢迎回关
已关注,欢迎回关
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
MySQL索引的本质,MySQL索引的实现,MySQL索引的数据结构
可以看到这是一颗二叉排序树,时间复杂度是和二分查找差不多的。每次都可以舍掉一半的数据。
手撕代码八百里
2021/04/20
2K0
MySQL索引的本质,MySQL索引的实现,MySQL索引的数据结构
一文搞懂MySQL索引(清晰明了)[通俗易懂]
索引是对数据库表中一列或多列的值进行排序的一种结构。MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。索引只是提高效率的一个因素,如果你的MySQL有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询语句。
全栈程序员站长
2022/09/12
1.4K0
一文搞懂MySQL索引(清晰明了)[通俗易懂]
Mysql索引原理及应用场景
在工作当中,涉及到Mysql的查询,我们经常会遇到给某个表某个字段加索引的诉求,加上索引能够让我们的sql得到查询速度上的提升。但索引的原理是什么呢,他又是怎么工作的,需要开发者对基础知识有一定的了解。
benym
2022/08/30
1.4K0
Mysql索引原理及应用场景
MySQL索引由浅入深
MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构,索引对于良好的性能非常关键,尤其是当表中的数据量越来越大时,索引对于性能的影响愈发重要。索引优化应该是对查询性能优化最有效的手段了。索引能够轻易将查询性能提高好几个数量级。
三分恶
2021/03/05
7870
MySQL索引由浅入深
SQL学习笔记五之MySQL索引原理与慢查询优化
一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,因此对查询语句的优化显然是重中之重。说起加速查询,就不得不提到索引了。
Jetpropelledsnake21
2019/02/15
9220
深入理解MySQL索引原理和实现——为什么索引可以加速查询?
说到索引,很多人都知道“索引是一个排序的列表,在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址,在数据十分庞大的时候,索引可以大大加快查询的速度,这是因为使用索引后可以不用扫描全表来定位某行的数据,而是先通过索引表找到该行数据对应的物理地址然后访问相应的数据。”
lyb-geek
2018/10/24
3.2K0
深入理解MySQL索引原理和实现——为什么索引可以加速查询?
MySQL索引详细
不使用索引,MySQL必须从第一条记录开始读完整个表,直到找出相关的行,表越大,查询数据所花费的时间就越多,如果表中查询的列有一个索引,MySQL能够快速到达一个位置去搜索数据文件,而不必查看所有数据,那么将会节省很大一部分时间。
全栈程序员站长
2022/07/09
5210
不懂就问,MySQL索引是啥?
索引是帮助数据库高效获取数据的一种数据结构,是基于数据表创建的,它包含了一个表中某些列的值以及记录对应的地址,并且把这些值存在一个数据结构中,常见的有使用哈希表、B+树作为索引。
唔仄lo咚锵
2022/05/08
1.4K0
不懂就问,MySQL索引是啥?
深入剖析 MySQL 索引和 SQL 调优实战(珍藏版)
MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等。
lyb-geek
2019/11/08
7480
【肝帝一周总结:全网最全最细】☀️Mysql 索引数据结构详解与索引优化☀️《❤️记得收藏❤️》
在关系数据库中,索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储数据结构,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。
苏州程序大白
2021/09/06
9080
2021春招 | 一口气搞懂MySQL索引所有知识点
国庆期间看了数据库的很多资料和书籍,这点我在总结的数据库文章里面也提过了,然后我发现我对索引的介绍不全,所以整理了一下自己的笔记,决定来个索引完整版,老规矩可能还是没我正常文章风格那么跳,但是干货一定也能让你有所收获。
王炸
2020/10/29
6740
2021春招 | 一口气搞懂MySQL索引所有知识点
彻底搞懂MySQL的索引
MyISAM和InnoDB是MySQL最常用的两个存储引擎,本文将进行详尽的介绍和对比。对于MySQL其余几种存储引擎,请读者自行搜索学习。
全菜工程师小辉
2019/08/16
9490
一文读懂MySQL的索引结构及查询优化
(同时再次强调,这几篇关于MySQL的探究都是基于5.7版本,相关总结与结论不一定适用于其他版本)
Python之道
2021/01/06
9110
MySQL索引的原理及使用
  上篇文章中学习了MySQL库的架构以及存储引擎,了解了基本索引(普通索引,唯一索引,主键索引),着重介绍了innerDB的存储方式以及内存模型,本篇文章和大家探讨一下MySQL库中索引的原理以及索引底层的数据结构。
会说话的丶猫
2020/08/06
1K0
MySQL索引的原理及使用
MySQL InnoDB索引:存储结构
此小结与索引其实没有太多的关联,但是为了便于理解索引的内容,添加此小结作为铺垫知识。
AlbertZhang
2020/09/21
1.3K0
MySQL 索引
  我们用一个例子来逐渐引出啥是索引。话说大老板东哥有一天想体验一下快递小哥的生活,就去自家快递公司准备干活了,一进仓库看到一地的快递,兴冲冲的就问旁边的快递小哥 “这么多快递,我要找一个人的快递怎么办?”。快递小哥说 “你可以一件件找,直到找到你要的那件快递”,东哥一听脸顿时黑了 “淦!上十万件快递你要我一件件找,是想累死我,然后继承我的白条吗?” 说完一甩手扭头就会豪宅去了。   第二天,快递公司老板去找东哥说 “领导,我们已经改进了,再去指导指导呗”。东哥一听,哎呀!动作挺快,然后就又到快递公司了,问 “你们想出什么办法了吗”。快递小哥连忙回答 “我们给所有的快递都编了号,做了一个表格,只要从表格中找到编号就可以找到快递了”,东哥心想,我从上十万的名单里找出了编码,还要去上十万的快递里扒出快递,还是太累了就说 “我时间有限有没有更快的办法”。   快递公司老板一听,这还得了,大 BOOS 不满意了,得亏有备用方案,就说 “领导,我们还有个方案,我们做个快递柜,1 ~ 10 号快递放 0 号,10 ~ 20 放 1 号,依次类推,只要找到了快递编码,很快就可以找到快递了”。东哥一听,不错哈!这么干就快多了,但是我还要从上十万的表格中找出编码,难受啊!一脸的难受。快递公司老板冷汗直流,这是嫌找编码满了啊,该怎么办,BOOS 一怒,回家种地。这时一个程序员站住来说 “领导,我们还有个方案,我们把表格进行优化,按照姓名首字母来分类,就可以很快的找到指定的名字和编码”。东哥大喜,升职加薪!   从上面的例子可以推出,如果没有索引,必须遍历整个表,直到指定快递被找到为止;有了索引之后,即可在索引中查找。由于索引是经过某种算法优化过的,因而查找次数要少的多。可见,索引是用来定位的。官方来讲就是:索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。
Demo_Null
2020/09/28
2K0
MySQL 索引
mysql 数据库引擎的区别
数据库引擎是用于存储、处理和保护数据的核心服务。利用数据库引擎可控制访问权限并快速处理事务,从而满足企业内大多数需要处理大量数据的应用程序的要求。 使用数据库引擎创建用于联机事务处理或联机分析处理数据的关系数据库。这包括创建用于存储数据的表和用于查看、管理和保护数据安全的数据库对象(如索引、视图和存储过程)。
Java编程指南
2019/08/02
3K0
mysql 数据库引擎的区别
相关推荐
MySQL索引的本质,MySQL索引的实现,MySQL索引的数据结构
更多 >
LV.0
这个人很懒,什么都没有留下~
作者相关精选
交个朋友
加入腾讯云官网粉丝站
蹲全网底价单品 享第一手活动信息
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档