简介
本文介绍MySQL的一些常见的语句优化。
in
in与exists
- in后的查询集合是确定且有限
- 集合内的值连续时,应尽可能使用between …and 。
- 集合内的值不连续时,用in,例如in (1,3,7)。
- in后的查询集合不确定。例如in (select…),应判断内查询与外查询的关系。
- 若内查询的表小于外查询的表,用in效率高。(因为in先执行内查询,再执行外查询)
- 若外查询的表小于内查询的表,用exists效率高。(因为exists先执行外查询,再执行内查询)
in与or
简介
- 如果in和or所在列有索引:or和in没啥差别,执行计划和执行时间都几乎一样。二者平手
- 如果in和or所在列没索引:性能差别就很大了。IN 胜出!
原因
MYSQL会对IN()里面的数据进行排序,然后用二分法查找其是否在列表中,这个算法的效率是O(logn),而等同的OR子句的查找效率是O(n)。
count(DISTINCT col) 与group by
count(distinct colA)就是将colA中所有出现过的不同值数量计算出来。也可以用group by完成
SELECT COUNT(DISTINCT colA) FROM table1; SELECT COUNT(1) FROM (SELECT colA FROM table1 GROUP BY colA);
区别(本质是时间与空间权衡)
项 | count(DISTINCT col) | group by |
原理 | distinct需要将colA中的所有内容都加载到内存中,大致可以理解为一个hash结构,key自然就是colA的所有值。因为是hash结构,那运算速度自然就快。最后计算hash中有多少key就是最终的结果。 海量数据环境下,需要将所有不同的值都存起来,内存消耗特别大,可能会out of memory | group by的实现方式是先将colA排序。排序大家都不陌生,拿最见得快排来说,时间复杂度为O(nlogn)O(nlogn),而空间复杂度只有O(1)O(1)。这样一来,即使数据量再大一些,group by基本也能hold住。但是因为需要做一次O(nlogn)O(nlogn) 的排序,时间自然会稍微慢点。 |
优缺点 | 优点:速度快 缺点:内存消耗大 | 优点:内存消耗小 缺点:速度稍慢 |
请先
!