ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

因为有了order by 反而加快了sql的执行--点解?

2021-03-05 22:05:38  阅读:138  来源: 互联网

标签:-- 点解 countintergal 索引 字段 sql active order


通过一个简单的案例,说明一下最优的执行计划应该是选择where条件上的 列的索引,或者应该选择 以 order by 字段上的索引?

如下图

图片

这样的一个简单sql, 两个表通过健值关联,where条件中除users.active=1,除此之外,再无其他有传值(=某个特定值)的条件 ,最后, 对出来的结果用countintergal字段以倒序排序。

分析执行计划:通过active列上的索引进行第一次查找 ,然后通过主键关联,去找另外一个表上的记录。视乎的确完全合理。因为where中只有active 字段有值。

实际上,这个sql的效率并不高,执行时间花掉了0.46sec. 原因是active列上等于1的值比较多,这个sql需要扫描几万条记录。


如果没有后面的order by 语句, 上面的sql确实无法再进行优化,对于users表,要么走active字段的索引进行查找, 要么就全表扫描,只有这两种结果。


一般来说,同样的sql语句,如where条件后还接有order by 的语句, 一般要比没有接order by 的语句要慢, 因为多了一个排序的操作。但在此sql中,反而我们可以恰恰利用order by字段进行快速查找,迅速找出需要的数据。


因为有基于countintergal字段排序,为了避免排序,我们在排序字段上建立一个索引。如下图

图片

然后我们再来分析与执行sql,居然发现执行计划没有任何改变,执行效率也么有变。-----不合符预期,索引白建了,why?

图片

为什么没有使用到新建立countintergal列上的索引,而是依然使用了active 字段上的索引? 这个就是mysql优化器的原因了,它“傻傻”地认为通过active字段上的索引进行查找应该是最优的,但实际上不是。


前面我们已经分析过,active 字段上的索引效率不高,同时,为了避免干扰了上述sql的执行计划, 所以决定删除active 列上的索引。


图片

如上图,删除掉索引之后,再来看执行计划,已经使用到了countintergal列上的索引,然后将sql执行,飕飕地出来结果。由之前的执行时间0.46s,瞬间变成0.01s.


   执行效率变高的原因: 因为结果是countintergal列倒序排序,且只取结果的前10行数据。所以,“我们”(实际上指mysql)可以通过从countintergal列的索引上取到countintergal值最大的记录,然后通过跟users关联获得一条关联后的结果,如果该条结果满足users.active的值等于1,则我们就获得了第一条记录。 如果不满足users.active等于1,则该条舍弃。 然后再从countintergal列的索引上取值第二大的,依次类推。最好的情况下,需要在countintergal列的索引查找10次,就完成了查找。所以效率比之前大大提高。


标签:--,点解,countintergal,索引,字段,sql,active,order
来源: https://blog.51cto.com/15057824/2648700

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有