索引
排好序的快速查找数据结构。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构,就是索引。下图就是一种可能的索引方式示例:
数据本身之外,数据库还维护着一个满足特定查找算法的数据结构,这些数据结构以某种方式指向数据,
这样就可以在这些数据结构的基础上实现高级查找算法,这种数据结构就是索引。
聚合索引
聚集索引一个表只能有一个,而非聚集索引一个表可以存在多个
聚集索引存储记录是物理上连续存在,而非聚集索引是逻辑上的连续,物理存储并不连续
聚集索引:物理存储按照索引排序;聚集索引是一种索引组织形式,索引的键值逻辑顺序决定了表数据行的物理存储顺序
非聚集索引:物理存储不按照索引排序;非聚集索引则就是普通索引了,仅仅只是对数据列创建相应的索引,不影响整个表的物理存储顺序.
索引是通过二叉树的数据结构来描述的,我们可以这么理解聚簇索引:索引的叶节点就是数据节点。而非聚簇索引的叶节点仍然是索引节点,只不过有一个指针指向对应的数据块。
https://www.cnblogs.com/s-b-b/p/8334593.html
https://www.cnblogs.com/shangfz/p/11270621.html
非聚合索引会造成二次查询的问题
前提 已经存在索引 areaId
实验:
# 查询的时候使用了索引
EXPLAIN SELECT areaID FROM area where areaID = '130103'
EXPLAIN SELECT areaID ,area FROM area where areaID = '130103'
# 查询过areaID的值后,又进行了二次查询得到 area
对于二次查询的问题, 可以使用下面的组合索引方式来解决!
组合索引 ( 覆盖索引 )
组合索引就是给数据库中的多列添加索,如添加一下的组合索引,其中组合索引先安装第一列排序,然后在第一列排序的基础上排序第二列,依次类推。如果第一列没有用到索引,那后面用到的索引也就会失效了。
(a,b,c)
根据mysql的最左匹配原则,从最左边开始匹配。
where a = 1 and b = 2 and c = 4 # 全部起作用
where b = 1 and a = 2 and c = 4 # 全部起作用 条件的顺序会优化
where b = 2 and c = 4 # 此时 a 是个断点,a后面的索引全部失效, 此写法组合索引无作用
where a = 1 and c = 2 # a 是起到作用的, c无作用
组合索引使用判断:
(0) select * from mytable where a=3 and b=5 and c=4;
abc三个索引都在where条件里面用到了,而且都发挥了作用
(1) select * from mytable where c=4 and b=6 and a=3;
这条语句列出来只想说明 mysql没有那么笨,where里面的条件顺序在查询之前会被mysql自动优化,效果跟上一句一样
(2) select * from mytable where a=3 and c=7;
a用到索引,b没有用,所以c是没有用到索引效果的
(3) select * from mytable where a=3 and b>7 and c=3;(范围值就算是断点)
a用到了,b也用到了,c没有用到,这个地方b是范围值,也算断点,只不过自身用到了索引
(4) select * from mytable where b=3 and c=4;
因为a索引没有使用,所以这里 bc都没有用上索引效果
(5) select * from mytable where a>4 and b=7 and c=9;
a用到了 b没有使用,c没有使用
(6) select * from mytable where a=3 order by b;
a用到了索引,b在结果排序中也用到了索引的效果,前面说了,a下面任意一段的b是排好序的
(7) select * from mytable where a=3 order by c;
a用到了索引,但是这个地方c没有发挥排序效果,因为中间断点了,使用 explain 可以看到 filesort
(8) select * from mytable where b=3 order by a;
b没有用到索引,排序中a也没有发挥索引效果
l
实验
1、创建索引
CREATE INDEX areaid_area_fatherid on area(areaID,area,fatherID)
2、测试最好
按照顺序查询的结果,符合最左原则。
EXPLAIN SELECT * from area WHERE areaID = '110116' AND area = '怀柔区' and fatherID = '110100'
3、测试不符合最左情况
EXPLAIN SELECT * from area WHERE area = '怀柔区' and fatherID = '110100'
把首列索引删去之后的查询效果, 3144行