今天我们再来研究一下mysql,探讨一下平常常用的sql语句是否有值得优化的地方。例如说我想查找表中重复的数据,一般我们会这样写,例如我们要查询sname这个字段重复的,一般我们会利用groupby来先分组,然后用having为我们筛选分组后的各组数据。
SELECT
s.id,s,sno,s.sname
FROM
student s
WHERE s.sname IN
(SELECT
t.sname
FROM
student t
GROUP BY t.sname
HAVING COUNT(t.sname) > 1)
在数据量极少的情况这样写是ok的,前提当数据量达到数十万甚至百万级别,你会发现groupby效率极其低下,所以一般我们会对分组字段添加索引。那么我们来加上索引后看看情况如何,我们就使用一般索引
---未加索引
共 20 行受到影响
执行耗时 : 7.062 sec
传送时间 : 0.003 sec
总耗时 : 7.066 sec
---添加索引后
共 20 行受到影响
执行耗时 : 1.118 sec
传送时间 : 0.003 sec
总耗时 : 1.122 sec
测试数据是50w条,添加和不添加索引,对比是明显的,时间接近相差了6-7倍。可想而知,当数据达到百万级别时的效率了。
那么我们能不能再优化呢?要不写个存储过程,尽管试试。
SELECT a.id,a.sno,a.sname FROM (SELECT
sname
FROM
student
GROUP BY sname
HAVING COUNT(sname) > 1) tmp
INNER JOIN student a
ON tmp.`sname` = a.`sname`
---未加索引时
共 20 行受到影响
执行耗时 : 6.456 sec
传送时间 : 0.003 sec
总耗时 : 6.460 sec
---添加索引后
共 20 行受到影响
执行耗时 : 0.269 sec
传送时间 : 0.003 sec
总耗时 : 0.273 sec
结果还是比较能接受的,当然这个未必是最优解,有同学有更好的想法可以给下思路。其实一般优化思路从两方面入手,最基本的是语句,再者就是索引。