类型
B+tree
特点
1. 树的高度比较低 这样可以减少磁盘的io次数 提高性能
2. 数据都在叶子节点 这样可以使查询更加稳定
3. 叶子节点使用指针相连, 这样更方便范围查询
hash
(InnoDB)聚簇索引: 叶子节点的索引键对应的是数据
(MyISM)非聚簇索引:叶子节点的索引键对应的是数据记录的id 还需要根据id查询对应的数据
查询过程
先对索引列的数据建立索引 存储在磁盘中,磁盘是分页的,存储时使用B+Tree的结构进行存储
然后查询时根据索引的key 查询对应的数据
那怎么在B+tree上找到对应的key呢? key计算hashcode
1、InnoDB存储引擎的最小存储单元是页,页可以用于存放数据也可以用于存放键值+指针,在B+树中叶子节点存放数据,非叶子节点存放键值+指针。
2、索引组织表通过非叶子节点的二分查找法以及指针确定数据在哪个页中,进而在去数据页中查找到需要的数据;
https://blog.csdn.net/u011389515/article/details/80192996
联合索引
联合索引的最左原则就是建立索引KEY union_index (a,b,c)时,等于建立了(a)、(a,b)、(a,b,c)三个索引
利用联合索引加速查询时,联合查询条件符合“交换律”,也就是where a = 1 and b = 1 等价于 where b = 1 and a = 1,这两种写法都能利用索引KEY union_index (a,b,c)。
(1) select * from myTest where a=3 and b=5 and c=4; ---- abc顺序
abc三个索引都在where条件里面用到了,而且都发挥了作用
(2) select * from myTest where c=4 and b=6 and a=3;
where里面的条件顺序在查询之前会被mysql自动优化,效果跟上一句一样
(3) select * from myTest where a=3 and c=7;
a用到索引,b没有用,所以c是没有用到索引效果的
(4) select * from myTest where a=3 and b>7 and c=3; ---- b范围值,断点,阻塞了c的索引
a用到了,b也用到了,c没有用到,这个地方b是范围值,也算断点,只不过自身用到了索引
(5) select * from myTest where b=3 and c=4; --- 联合索引必须按照顺序使用,并且需要全部使用
因为a索引没有使用,所以这里 bc都没有用上索引效果
(6) select * from myTest where a>4 and b=7 and c=9;
a用到了 b没有使用,c没有使用
(7) select * from myTest where a=3 order by b;
a用到了索引,b在结果排序中也用到了索引的效果,a下面任意一段的b是排好序的
(8) select * from myTest where a=3 order by c;
a用到了索引,但是这个地方c没有发挥排序效果,因为中间断点了,使用 explain 可以看到 filesort
(9) select * from mytable where b=3 order by a;
b没有用到索引,排序中a也没有发挥索引效果
NULL影响
可以看到存在NULL值,innodb也会走索引,那么空字符呢?
继续测试发现无论字符类型的列中存储的是NULL还是空字符''都是会走索引的
索引失效的条件
不在索引列上做任何操作(计算、函数、(自动or手动)类型转换),会导致索引失效而转向全表扫描
存储引擎不能使用索引范围条件右边的列
尽量使用覆盖索引(只访问索引的查询(索引列和查询列一致)),减少select *
mysql在使用不等于(!=或者<>)的时候无法使用索引会导致全表扫描
is null,is not null也无法使用索引
like以通配符开头(’%abc…’)mysql索引失效会变成全表扫描的操作。问题:解决like‘%字符串%’时索引不被使用的方法?