MySQL主键索引非主键索引以及SQL语句中如何利用索引的
Posted liu++
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL主键索引非主键索引以及SQL语句中如何利用索引的相关的知识,希望对你有一定的参考价值。
mysql(3)主键索引、非主键索引以及SQL语句中如何利用索引的
在之前写的MySQL(1)里面介绍了mysql的数据是以B+Tree的数据结构存储的,存在ibd文件里面,那篇说实话写的不好,这篇再细说一下索引。
主键索引——》MySQL中数据是怎么存的
MySQL在5.5以后使用InnoDB为默认存储引擎,在InnoDB中主键索引为聚簇索引,什么是聚簇索引呢?就是索引和数据存在一起,在InnoDB中主键索引和数据构成B+Tree。
在叶子结点是存的这一行数据,非叶子节点存的是主键的值。然后说一下MyISAM存储引擎,它里面的索引都是非聚簇索引,数据是一个文件,索引是单独的文件,里面索引存的是数据的地址。
非主键索引——》非主键索引存在哪
在InnoDB引擎中非主键索引是非聚簇索引,它是存在索引表里面的用户不好看到(应该),下面贴出我的问答:
ok很久以来的疑惑解除了,之前看有篇文章说一个索引对应一棵B+Tree,是的没有问题,之前疑惑的是普通索引是要把数据都复制一遍吗,不是要B+Tree吗?
答:不需要复制全部数据,只需要复制索引的字段和主键,主键索引对应B+Tree的叶子结点是整行数据,普通索引对应的B+Tree叶子结点是主键。
MySQL是如何利用索引的
SQL语句在经过分析与优化之后确定了走哪个索引,我们在写SQL语句的时候一定要用EXPLAIN
查看一下这条SQL使用的索引,例如:
EXPLAIN的结果里面主要看type,ALL就是没走索引,能优化就优化不能优化就算了。
常用的类型有: ALL、index、range、 ref、eq_ref、const、system、NULL(从左到右,性能从差到好)
我之前看一些文章说要想性能过得去这个type至少要达到range如何查看sql查询是否用到索引(mysql),确实,但是索引占的是存储空间,而且影响update、add、delete,自己取舍一下找一下平衡。
覆盖索引、最左前缀、索引下推
如何触发索引其实是书写SQL语句时要注意的!比如最左前缀、覆盖索引,下面逐一说明一下。
虽然使用了索引但是还要回表
,回表就是根据普通索引k查,查到的是主键,要想获得行数据还需要根据主键在主表查一次,这样一条SQL语句就查询了两次,我们要尽量减少回表索引:
- 覆盖索引:看SQL语句
SELECT id FROM xx WHERE k=?
SELECT * FROM xx WHERE k=?
第一条语句把索引覆盖住了,只查k这颗B+Tree就行了,因为返回结果只有id,查k不就是能获得id吗,第二条显然没有覆盖住还需要回表,根据id查行数据。
所以说不要无脑写*
,根据需求,按需供给,按需供给的好处是可能触发覆盖索引,并且查的数据少了网络占用也就下了,传输方便了。
- 最左前缀:主要是针对like、or这种,以及联合索引,比如
where name like '张%'
where name like '%张'
第二句即使name有索引也触发不了,还有就是联合索引的问题,如果是(name,age)联合索引,那你查的时候只查age是触发不了索引的!!
- 索引下推:索引下推是MySQL5.6之后的功能,处理多条件的情况,先看代码
select * from tuser where name like '张 %' and age=10
这个name索引触发了但是age索引没有触发,在MySQL5.6之前是通过name获得id再获得行数据,在这些行数据里面去筛选age。
在MySQL5.6之后有了索引下推,这个索引下推主要是作用在联合索引,在每个索引都是一个字段的时候并没有特别大的作用。有了索引下推之后利用(name,age)这个联合索引,因为(name,age)这颗B+Tree包含name字段包含age字段,所以虽然只触发了name但是后面有age也就顺便把age判断了。
总结
这篇还是没有什么特别新的东西比较遗憾希望对读者有帮助吧。
参考
以上是关于MySQL主键索引非主键索引以及SQL语句中如何利用索引的的主要内容,如果未能解决你的问题,请参考以下文章