33

mysql优化篇:where中的like和=的性能分析

 3 years ago
source link: https://segmentfault.com/a/1190000023822275
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

一、引言

那使用过数据库的人大部分都知道,like和=号在功能上的相同点和不同点,那我在这里简单的总结下:
    1,不同点:like可以用作模糊查询,而'='不支持此功能;如下面的例子,查询info表中字段id第一个字母为1的数据:
select * from info where id like '1%';
2,相同点:like和"="都可以进行精确查询,
比如下面的例子,从结果上看,都是查询info表中字段id等于'12345'的结果:
select * from info where id like '12345';
以上就是返回结果中,like和'='中的相同和不同点。那好奇的小伙伴可能就要问了,那执行过程呢?mysql不管是遇到like还是'='时的执行过程也都是一样的么?

bMvQFfE.png!mobile

没错,事情不能只看表面,如果你细心研究,就会发现其实like和等于号'='并不是那么简单,下面我们将详细的分析他们两者的真正区别~~~

二、正文

首先,我们来介绍一下mysql中的explain关键字;explain是执行计划的意思,即通过该命令查看这条sql是如何执行的。

使用方法也很简单,即 explain + sql语句 ,例如:

explain select * from info where id like '12345';

具体对于explain关键字的介绍我会将在以后的博客中总结,目前不懂得小伙伴可以自行百度。。。

bMvQFfE.png!mobile

那我们来使用explain测试一下like和=下的查询情况,首先我们来测试一下为索引的字段:

EXPLAIN SELECT
    * 
FROM
    crms_customer 
WHERE
    id = '7cf79d7c8a3a4f94b5373b3ec392e32d';

z6vyim.png!mobile

而现在我们把"="换成like试一下:

EXPLAIN SELECT
    * 
FROM
    crms_customer 
WHERE
    id LIKE '7cf79d7c8a3a4f94b5373b3ec392e32d';

zaIBJ3.png!mobile

小伙伴通过对比可以看到两条返回结果的type字段和Extra字段中的数据有所不同,那为什么不同,他们所代表的含义是什么呢?

type字段:

type字段是一个可选值,这些值的性能从低到高的排序如下:

type 说明 SYSTEM 系统,表仅有一行(=系统表)。这是const联接类型的一个特例 CONST 常量,表最多有一个匹配行,因为仅有一行,在这行的列值可被优化器剩余部分认为是常数,const表很快,因为它们只读取一次 EQ_REF 搜索时使用primary key 或 unique类型 REF 根据索引查找一个或多个值 INDEX_MERGE 合并索引,使用多个单列索引搜索 RANGE 对索引列进行范围查找 index 全索引表扫描 ALL 全数据表扫描

根据表格可以明显看出,其中const是常量查找,而RANGE是对索引列进行范围查找,所以性能也就很明显的体现了出来。

那使用like查询时,Extra字段代表什么呢?Extra字段中的Using where,又代表什么?

Extra字段

1,Extra字段是Explain输出中也很重要的列,所代表着MySQL查询优化器执行查询的过程中对查询计划的重要补充信息。

2,Extra字段中的Using where意味着mysql服务器将在存储引擎检索行后再进行过滤。所以比起使用使用'='又多了一步查找过程。

显然通过以上的总结我们可以得出结论:当我们使用索引字段进行条件查询时,'='的性能要比like快。

是不是以为到这里就结束了呢?

然而并没有

Ar6FBfM.png!mobile

有的小伙伴该问了那非索引字段呢?

对的,我们下面继续测试非索引字段

EXPLAIN SELECT
    * 
FROM
    crms_customer 
WHERE
    customer_name = '张飞';
-----------------------------------
    
EXPLAIN SELECT
    * 
FROM
    crms_customer 
WHERE
    customer_name LIKE '张飞';

除了"="和like同样的两条语句,让我们运行一下:

"=":

uYBJ32R.png!mobile

like:

aiyqye3.png!mobile

可以看出当非索引字段时like和"="是一样的,性能上也没有差别。

结论

经过我们的不懈努力,可以得到结论:当like和"="在使用非索引字段查询时,他们的性能是一样的;而在使用索引字段时,由于"="是直接命中索引的,只读取一次,而like需要进行范围查询,所以"="要比like性能好一些。~~~~


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK