首先必须了解几个概念:单列索引,复合索引,最左前缀原则(我自己起名为:通关有序原则)
1. 索引建立的原则
用于索引的最好的备选数据列是那些出现在WHERE子句、join子句、ORDER BY或GROUP BY子句中的列。
仅仅出现在SELECT关键字后面的输出数据列列表中的数据列不是很好的备选列
2.单列索引
举个栗子
索引index(lname)
走索引情况
SELECT `uid` FROM people WHERE lname`='Liu'
3.复合索引
举个栗子
索引index(a,b,c)
不会走索引情况
select * from table where c = '1'
select * from table where b =‘1’ and c ='2'
会走索引情况
select * from table where a = '1'
select * from table where a = '1' and b = ‘2’
select * from table where a = '1' and b = ‘2’ and c='3'
原因:索引index(a,b,c),只会走a、a,b、a,b,c 三种类型的查询(ac同样也会走,但是只使用a索引,不会使用c索引)
注:select * from table where a = '1' and b > ‘2’ and c='3'
这种情况只会走a,b为什么?因为索引是有序的,走索引会先根据a排序,再根据b排序(由于b是范围查找并未有序,故c无法使用索引(即无序状态))
个人理解小结:
1.如上复合索引犹如通关,想过第二关必须通过第一关,第一关的状态必须是win赢而不是输,也就是a必须走索引,状态是有序并不是无序。->这里体现了我上面所说的最左前缀原则中的最左(即通关有序原则)
2.我们创建了index复合索引,相当于创建了(a)单列索引,(a,b)组合索引以及(a,b,c)组合索引。这里应该体现了前缀了吧(赶脚不太明显哈)
下面有两个经典的栗子,我在这里引用一下
CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`cid` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `name_cid_INX` (`name`,`cid`),
KEY `name_INX` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8
执行1:
EXPLAIN SELECT * FROM student WHERE name='小红'; //type=ref
执行2:
EXPLAIN SELECT * FROM student WHERE cid=1; //type=index
执行3:
EXPLAIN SELECT * FROM student WHERE cid=1 AND name='小红'; //type=ref
1.上面竟然可以使用索引?
是的
解释:
index:mysql会扫描索引列表,只要是索引或者复合索引的一部分,才会使用index
ref:mysql会根据特定的算法快速查找到某个符合条件的索引,而不是会对索引中每一个数据都进行一 一的扫描判断,也就是所谓你平常理解的使用索引查询会更快的取出数据。
分析执行3
索引是index(name,cid)
2.查询的语句是cid=1 AND name='小红'; 我是先查询cid,再查询name的,不是先从最左面查的呀?
首先我可以确定的是两种情况查询效率是一样的(cid=1 AND name='小红';/name='小红' AND cid=1;)
主要是由于mysql优化器的作用:mysql优化器会调整sql的顺序,来保证sql可以最高效利用索引,保证查询效率。
(ainusers原创)最左前缀原则【BTree索引支持】
最新推荐文章于 2023-06-28 12:00:00 发布