精通MySQL之索引篇,这篇注重练习!
老刘是即将找工作的研究生,自学大数据开发,一路走来,感慨颇深,网上大数据的资料良莠不齐,于是想写一份详细的大数据开发指南。这份指南把大数据的【基础知识】【框架分析】【源码理解】都用自己的话描述出来,让伙伴自学从此不求人。 大数据开发指南地址如下:
github:https://github.com/BigDataLaoLiu/BigDataGuide 码云:https://gitee.com/BigDataLiu/BigDataGuide 您的点赞是我持续更新的动力,禁止白嫖,看了就要有收获,有需要联系公众号:努力的老刘。
今天给大家分享的是大数据开发基础部分MySQL的索引篇,这篇内容大家一定要跟着练习,不然等于白看!
索引是什么?
在日常开发中常常会遇到查询比较慢的情况,我们的第一反应就是给它加索引,那索引是什么呢?官方介绍索引是帮助MySQL高效获取数据的数据结构,数据库索引好比是一本书的目录,能加快数据库的数据查询速度。
那索引的好处有哪些呢?
它可以提高数据检索的效率,降低数据库的成本。 通过索引对数据进行排序,降低数据排序的成本,降低CPU消耗。
任何事情都会有正反面,索引也不例外,那索引的坏处有哪些呢?
索引会占据磁盘空间。 索引虽然会提高查询效率,但会降低更新表的效率。 MySQL不仅要保存数据,还有保存或者更新对应的索引文件。
那是不是有坏处就不用索引呢?
当然不是,索引必须拿来。一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往是存储在磁盘文件上的文件中。
索引的分类
单列索引: 普通索引:add unique 唯一索引:索引列中的值必须是唯一的,但允许有空值,add unique index 主键索引:是一种特殊的唯一索引,不允许有空值
组合索引: 在表中的多个字段组合上创建的索引 组合索引的使用,需要遵循最左前缀原则 一般情况下,建议使用组合索引代替单列索引(主键索引除外)
全文索引:只有在MyIsam、InnoDB上才能使用,而且只能在char、varchar、text类型字段上使用全文索引。 空间索引:一般用不到
索引的使用
创建索引
CREATE INDEX index_name ON table(column(length)) ;
删除索引
DROP INDEX index_name ON table;
查看索引
SHOW INDEX FROM table_name \G;
索引原理(重点)
索引的存储结构
说索引原理之前,先说说索引存储结构。索引是在存储引擎中实现的,也就是不同的存储引擎,会使用不同索引。其中MyIsam和InnoDB只支持B+数索引,老刘先不讲B树和B+树的概念,大家自行搜索。
接下来就是索引的重点,搞清楚了非聚集索引和聚集索引,索引原理就差不多了!
非聚集索引(MyIsam)
它说的是B+树叶子节点只会存储数据行(数据文件)的指针,即数据和索引不在一起。它包含主键索引和辅助索引,都会存储指针的值。
主键索引
MyIsam中B+树叶子节点存储的数据是数据的指针值,通过索引树找到对应的索引,然后通过索引中存储的记录指针,找到数据文件中对应的记录。
辅助索引(次要索引)
在MyIsam中,主索引和辅助索引在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key是可以重复的。
聚集索引(InnoDB)
主键索引(聚集索引)的叶子节点会存储数据行,也就是说数据和索引在一起。 辅助索引只会存储主键值。 如果没有主键,则使用唯一索引建立聚集索引;如果没有唯一索引,MySQL会按照一定规则创建聚集索引。
主键索引
在InnoDB中要求表必须有主键(MyIsam可以没有),如果没有显示指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键类型为长整形。
上图是 InnoDB 主索引(同时也是数据文件)的示意图,可以看到叶节点包含了完整的数据记录,这种索引叫做聚集索引。因为 InnoDB 的数据文件本身要按主键聚集。
辅助索引
InnoDB 的辅助索引 data 域存储相应记录主键的值而不是地址。换句话说,InnoDB 的所有辅助索引都引用主键作为 data 域。
聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录,即回表查询。
select * from user where name='Alice'
根据这段SQL语句,会进行回表查询,检索两次,才会获得记录。回表性能比较低,尽量做到不回表。
索引使用场景
介绍完索引的相关概念后,老刘必须给讲讲哪些场景下可以使用场景,大家记几个就行。
哪些情况下需要使用索引
主键自动建立唯一索引 频繁作为查询条件的字段应该创建索引 多表关联查询中,关联字段应该创建索引 查询中排序的字段应该创建索引 频繁查询字段 查询中统计或者分组字段应该创建索引
哪些情况下不需要创建索引
表记录太少,没必要创建索引 经常进行增删改的表 频繁更新的字段 where条件里使用频率不高的字段
为什么推荐多使用组合索引?
为了节省mysql索引存储空间以及提升搜索性能,能使用组合索引就不使用单列索引。
使用组合索引需要遵循最左前缀原则,什么是最左前缀原则?
前缀索引:where like a%
通配符%在右边不在左边,什么是前缀索引呢?当索引是很长的字符序列时,这个索引会很慢,占用内存。如果以name为索引,当name对应的字符串很长时,就可以用前缀索引where like a%。
从左到右都有索引,不能断,直到遇到范围查询<,>,between。
索引失效
我们进行数据查询很慢时,可能就会存在索引失效的情况。遇到这种情况不要怕,我们可以使用explain命令对select语句的执行计划进行分析。explain出来的信息有10列,分别是
id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra
下面老刘就使用一个案例进行这些参数进行说明,大家可以跟着老刘一起练习。这10个参数老刘只讲重要的,其他的大家自行学习。
--用户表
create table tuser(
id int primary key,
loginname varchar(100),
name varchar(100),
age int,
sex char(1),
dep int,
address varchar(100)
);
--部门表
create table tdep(
id int primary key,
name varchar(100)
);
--地址表
create table taddr(
id int primary key,
addr varchar(100)
);
--创建普通索引
mysql> alter table tuser add index idx_dep(dep);
--创建唯一索引
mysql> alter table tuser add unique index idx_loginname(loginname);
--创建组合索引
mysql> alter table tuser add index idx_name_age_sex(name,age,sex);
--创建全文索引
mysql> alter table taddr add fulltext ft_addr(addr);
id
每个SELECT语句都会自动分配的一个唯一标识符,表示查询中操作表的顺序,有四种情况:
id相同:执行顺序由上到下 id不同:如果是子查询,id号会自增,id越大,优先级越高。 id相同的不同的同时存在 id列为null的就表示这是一个结果集,不需要使用它来进行查询。
select_type(重要)
表示查询类型,主要用于区别普通查询、联合查询(union、union all)、子查询等复杂查询。
simple,表示不需要union操作或者不包含子查询的简单select查询。
primary,一个需要union操作或者含有子查询的select,位于最外层的单位查询的select_type即为primary,并且只有有一个 。
先执行括号里面的sql语句,再执行外面的sql语句,内层的查询就是subquery。
subquery,除了from字句中包含的子查询外,其他地方出现的子查询都可能是subquery。
dependent subquery,表示这个subquery的查询要受到外部表查询的影响。
union,它连接的两个select查询,第一个查询是PRIMARY,除了第一个表外,第二个以后的表select_type都是union。
dependent union,它与union一样,出现在union 或union all语句中,但是这个查询要受到外部查询的影响。
union result,它包含union的结果集,在union和union all语句中,因为它不需要参与查询,所以id字段为null。
derived,from字句中出现的子查询,也叫做派生表,其他数据库中可能叫做内联视图或嵌套select。
可以理解为就是from字句后面出现子查询,取个别名,叫派生表。
table
显示查询的表名,如果查询使用了别名,那么这里显示的是别名。
type(重要)
它会显示很多参数类型,性能依次从好到坏显示为这样:
system,const,eq_ref,ref,fulltext,ref_or_null,unique_subquery,index_subquery,range,index_merge,index,ALL
除了all之外,其他的type都可以使用到索引,除了index_merge之外,其他的type只可以用到一个索引,优化器会选用最优索引一个,最少要索引使用到range级别。 老刘只讲这个重要的,有些内容也没搞清楚。
system
可遇不可求,表中只有一行数据或是空表。
const(重要)
使用唯一索引或主键,返回记录一定是1行记录的等值where条件。
eq_ref(重要)
一般是连接字段主键或者唯一性索引。
此类型通常出现在多表的 join 查询,表示对于前表的每一个结果,都只能匹配到后表的一行结果。并且查询的比较操作通常是 '=',查询效率较高。
ref(重要)
针对非唯一性索引,使用等值(=)查询非主键。或者是使用了最左前缀规则索引的查询。
range(重要)
索引范围扫描,常见于使用>,<,is null,between ,in ,like等运算符的查询中。
index(重要)
关键字:条件是出现在索引树中的节点的,可能没有完全匹配索引。
索引全表扫描,把索引从头到尾扫一遍,常见于使用索引列就可以处理不需要读取数据文件的查询、可以使用索引排序或者分组的查询。
all(重要)
这个就是全表扫描数据文件,然后再在server层进行过滤返回符合要求的记录。
possible_keys、key、key_len、ref、rows就不讲了,直接讲最后一个extra。
extra
这个列包含不适合在其他列中显示单十分重要的额外的信息,这个列可以显示的信息非常多,有几十种,这里写常见的几种。
no tables used
表示不带from字句的查询,使用not in()形式子查询或not exists运算符的连接查询,这种叫做反连接。一般连接查询是先查询内表,再查询外表,反连接就是先查询外表,再查询内表。
using filesort(重要)
排序时无法使用到索引时,就会出现这个,常见于order by和group by语句中。
using index(重要)
查询时不需要回表查询,直接通过索引就可以获取查询的数据。
using where(重要)
通常type类型为all,记录并不是所有的都满足查询条件,通常有where条件,并且一般没索引或者索引失效。
讲完分析索引的参数后,现在老刘讲一些索引失效的情况,大家一定要用心记住,老刘也记了好几遍!
索引失效分析
一般SQL语句查询采用全值匹配,资料上叫全值匹配我最爱。
最左前缀法则,对于组合索引而言,查询从索引的最左前列开始,并且不能跳过索引中的列不然就会失效。
现在举一个带头的索引断(带头索引生效,其他索引失效)的例子:
不要在索引上做计算,例如计算、函数、自动/手动类型转换,不然会导致索引失效而转向全表扫描。
范围条件右边的列失效,就是不能继续使用索引中范围条件(bettween、<、>、in等)右边的列。
尽量使用覆盖索引(只查询索引的列),也就是索引列和查询列一致,减少select *。
索引字段上不要使用不等,索引字段上使用(!= 或者 < >)判断时,会导致索引失效而转向全表扫描。
主键索引字段上不可以判断null,索引字段上使用 is null 判断时,可使用索引。
索引字段使用like以通配符开头(‘%字符串’)时,会导致索引失效而转向全表扫描。like要以通配符结束相当于范围查找,索引不会失效。
索引字段是字符串时,要加单引号,否则会导致索引失效而转向全表扫描。
索引字段不要使用or,否则会导致索引失效而转向全表扫描。
总结
这篇内容大家一定要跟着老刘练习,光看不练等于白学!尽管当前水平可能不及各位大佬,但老刘会努力变得更加优秀,让各位小伙伴自学从此不求人!
如果有相关问题,联系公众号:努力的老刘。文章都看到这了,点赞关注支持一波!
精通MySQL之索引篇,这篇注重练习!的更多相关文章
- MySQL的索引(中)
连着发了几天文章,从我收到的反映来说,大家觉着还不错,可以很清晰的看到知识的脉络,但是这个还不错是针对传统的文章的无聊.不明确.完全不考虑考虑用户体验的角度上对比出来的.掌握一门知识还是不容易的,有的 ...
- mysql学习【第5篇】:事务索引备份视图
狂神声明 : 文章均为自己的学习笔记 , 转载一定注明出处 ; 编辑不易 , 防君子不防小人~共勉 ! mysql学习[第5篇]:事务索引备份视图 MySQL事务 事务就是将一组SQL语句放在同一批次 ...
- Mysql高手系列 - 第21篇:什么是索引?
Mysql系列的目标是:通过这个系列从入门到全面掌握一个高级开发所需要的全部技能. 这是Mysql系列第21篇. 本文开始连续3篇详解mysql索引: 第1篇来说说什么是索引? 第2篇详解Mysql中 ...
- Mysql高手系列 - 第22篇:深入理解mysql索引原理,连载中
Mysql系列的目标是:通过这个系列从入门到全面掌握一个高级开发所需要的全部技能. 欢迎大家加我微信itsoku一起交流java.算法.数据库相关技术. 这是Mysql系列第22篇. 背景 使用mys ...
- Mysql高手系列 - 第24篇:如何正确的使用索引?【高手进阶】
Mysql系列的目标是:通过这个系列从入门到全面掌握一个高级开发所需要的全部技能. 欢迎大家加我微信itsoku一起交流java.算法.数据库相关技术. 这是Mysql系列第24篇. 学习索引,主要是 ...
- MySQL全面瓦解24:构建高性能索引(策略篇)
学习如果构建高性能的索引之前,我们先来了解下之前的知识,以下两篇是基础原理,了解之后,对面后续索引构建的原则和优化方法会有更清晰的理解: MySQL全面瓦解22:索引的介绍和原理分析 MySQL全面瓦 ...
- 白日梦的MySQL专题(第38篇文章)8分钟回顾MySQL的索引
目录 公众号首发-推荐阅读原文-格式更好看 一.导读 二.聚簇索引 三.二级索引 四.联合索引 4.1.什么是联合索引 4.2.左前缀原则 4.3.联合索引的分组&排序 五.覆盖索引 六.倒排 ...
- mysql学习【第4篇】:MySQL函数和编程
狂神声明 : 文章均为自己的学习笔记 , 转载一定注明出处 ; 编辑不易 , 防君子不防小人~共勉 ! mysql学习[第4篇]:MySQL函数 官方文档 : 官方文档 常用函数 分类: 数学函数 , ...
- mysql学习【第2篇】:MySQL数据管理
狂神声明 : 文章均为自己的学习笔记 , 转载一定注明出处 ; 编辑不易 , 防君子不防小人~共勉 ! mysql学习[第2篇]:MySQL数据管理 外键管理 外键概念 如果公共关键字在一个关系中是主 ...
随机推荐
- [leetcode]Q133Clone Graph
克隆图记住:一个map一个queue,照葫芦画瓢BFS 找到一个节点就画一个对应的新的,用map对应,然后添加邻居,记录邻居到queue public UndirectedGraphNode clon ...
- Linux嵌入式学习-烟雾传感器驱动-字符设备驱动-按键驱动
MQ-2烟雾气敏传感器模块在X210v3开发板上的驱动. 现在需要一个MQ-2烟雾气敏传感器模块的驱动.其检测烟雾超过一定的标准后,会返回一个不同的电平,和按键驱动差不多. 但是在编写驱动的时候,需要 ...
- Android Studio连接手机调试教程已决解
Android Studio连接手机调试教程 Windows电脑连接安卓手机需要下载安装驱动,确保电脑联上网络. 准备条件: 1.电脑上安装应用宝软件. 2.手机开发者选项里面打开USB调试,USB安 ...
- 什么是Cassandra数据库
在本文中,我们将介绍Cassandra名字的含义.Cassandra的发展简史.Cassandra这项技术的特点及优势,以及对于这项技术的未来展望. 本文将用浅显易懂的方式,帮助您将对Cassandr ...
- 7.24,《C Primer Plus》复习第十五章第二小题
编写一个程序,通过命令行参数读取两个二进制字符串,对这两个二进制数使用~运算符,&运算符.|运算符,并以二进制字符串形式打印结果(如果无法使用命令行环境,可以通过交互式让程序读取字符串) 编写 ...
- JavaScript入门-学习笔记(一)
JavaScript入门(一) 学习js之前,我们先来了解一下,什么是JavaScript? JavaScript是一种解释型语言.在运行的时候,一边读一边编译一边执行.简单来说就是,在执行js代码时 ...
- 如何使用容器镜像服务 TCR 轻松实现容器 DevOps
作者周明,腾讯云容器产品工程师.目前主要负责腾讯云TKE.TCR等产品控制台的相关研发工作. 概述 当你使用云厂商提供的容器服务部署业务服务后,是否对交付部署全链路的效率有更高的需求,例如实现基于容器 ...
- JavaCV FFmpeg AAC编码
上次成功通过FFmpeg采集麦克风的PCM数据,这次针对上一次的程序进行了改造,使用AAC编码采集后的数据. (传送门) JavaCV FFmpeg采集麦克风PCM音频数据 采集麦克风数据是一个解码过 ...
- Hbase Rowkey设计原则
Hbase是三维有序存储的,通过rowkey(行键),column key(column family和qualifier)和TimeStamp(时间戳)这三个维度可以对HBase中的数据进行快速定位 ...
- SQL操作符的优化
操作符优化 IN 操作符 用IN写出来的SQL的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格. 但是用IN的SQL性能总是比较低的,从ORACLE执行的步骤来分析用IN的SQ ...