如何判断一个sql走不走索引?

发布时间 2023-12-21 20:04:01作者: 天NULL

在你的工作中,可能写过很多个sql,我相信最让你头疼的,一定还是那风骚的查询sql。

我猜你很可能有这样的体验,好不容易写了一个牛逼哄哄的查询sql,兴奋的上线投产。

结果,在第二天阳光明媚的日子里,dba把你的sql揪了出来,揪出来还不算,dba还要发到群里@你,说:“嗨,兄弟,瞅瞅你写的个啥?”

接着,dba把你苦思冥想的sql贴在群里,这时,是不是感觉自己的内裤被扒出来展览一样?

对的,慢sql,是业务研发做sql优化逃避不了的一个问题。

要避免慢sql,最重要的,就是索引。

聪明的你应该看出来了,我要讲一讲,如何判断一个sql走不走索引?

以mysql为例,你可能马上就要骂我:“这还不简单,explain一下不就完事?”

是的,你很聪明,不过explain出来的结果,你得明白为什么,这样才能知道如何解决以及优化。

接着,来一起浪一把!

先创建如下表:

create table t1(id int primary key, a int, b int,c varchar(16),d varchar(16) index(a), index(c,d));

然后,我写了五个sql,你瞅瞅看走不走索引。

select * from t1 where a>5;

select * from t1 where c='test';

select * from t1 where c like 'test%';

select * from t1 where d like 'test%';

select * from t1 where c like '%test';

可能你已经知道答案了,如下:

select * from t1 where a>5;  //走索引

select * from t1 where c='test';  //走索引

select * from t1 where c like 'test%';  //走索引

select * from t1 where d like 'test%'; //不走索引

select * from t1 where c like '%test';  //不走索引

那原理是什么呢?

mysql的表数据,本质上就是一个写在磁盘的B+树,专业名词叫做聚簇索引。而其他的索引,也是以B+树的形式写在文件中。

B+树的数据,不是顺序的,但却是有序的。

这就意味着,比如select * from t1 where a>5; 这个sql的a>5,从数据结构上,是可以推出来数据的大致位置的,既然如此,那便无需全表扫描,可以用到索引a。mysql,也正是这么做的。

理解了范围查询能走索引,接下来看第2个sql

select * from t1 where c='test';

由于c、d两个字段有组合索引,将第2个sql做一下改造

等价于

select * from t1 where c='test' and c||d>='test';

这下明白了不?有了范围查询,那就能走索引了。

再来看第3个sql,同理:

等价于

select * from t1 where c like 'test%' and c||d>='test';  

所以,还是能够走索引。

再来看第4、5个sql,咱费劲脑子,也做不了如上的等价sql转换,事实上,这两个sql确实也走不了索引。

说到这,我想你大概想到了一个专业名词:最左匹配原则。

对,就是这个原则,而这个原则的算法依据,便是我所阐述的。

希望看了这篇文章,能对你有些帮助,不再被dba轻易抓住。