一、explain 关键字
在弄懂MySQL索引的最左匹配原则之前,我们需要先了解一下 explain 关键字
我在学习explain关键字的时候找到了一张很好的图,但是我现在找不到出处了,只记得是在思否上面的,如果侵权联系我删掉
二、创建数据库
create table test(a int ,b int,c int,d int,key index_abc(a,b,c))engine=InnoDB default charset=utf8;
向数据库里面插入1000条数据
DROP PROCEDURE IF EXISTS proc_initData;DELIMITER $CREATE PROCEDURE proc_initData()BEGINDECLARE i INT DEFAULT 1;WHILE i<=10000 DO INSERT INTO test(a,b,c,d) VALUES(i,i,i,i); SET i = i+1;END WHILE;END $CALL proc_initData();
这样我们就插入了1000条数据,和创建了 a b c 的联合索引
三、最左匹配原则
我们知道给字段创建了索引,只有我们使用了该字段,才会使用上索引,上面创建了联合索引 abc,假设我们不知道索引的使用规则,我们以最基本的思考,a、b、c,三个变量能够组合成多少种情况呢?
注:本来这个地方是表格的,但是为了手机上好浏览,我就给它截图了。
上面代码都是sql,如果你想验证是否使用索引,在sql前面加上 explain 关键字即可
从上面的表格中我们可以做如下总结(也就是最左匹配原则了)
索引的使用只和字段有关,和字段的排序无关
从上面我们可以得出,创建了4个索引,a、ab、ac、abc(注意排序无关)
最左匹配原则就是只要 使用到了组合索引的第一个,索引即可生效
本以为今天的工作是可以开开心心的写接口,但还是出了大问题。
相同的代码,换个数据库就查询不出数据
今天下午在测试环境发现访问不到数据,反复检查代码,发现是下面这段代码有问题,但是代码很简单看不出任何问题。
<if test="name != null and name != ''"> AND ctm.ctm_name = #{name}if>
它也没有报错,sql打印出来也正常,复制到navicat里面也能正常查询出数据,我使用我本地的环境就没问题,换上测试库就是没有数据。
后面没办法就把测试库的相关表复制过来,但是还是不行。
然后我又重新开了一个库,把我本地的数据导入测试没问题,把测试库的数据导入也没有问题。
最后折腾了半天,发现是连接的时候字符集出了问题。(其实之前已经对比过数据库的字符集没有任何问题)
正确的字符集如下:
?useUnicode=true&AutoReconnect=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
这种问题是真的难以发现,完全没有想到是这里的问题,因为其它sql执行都是没问题的。