SQL里进行分组的时候,如何才能使用索引?
SQL里进行分组的时候,如何才能使用索引?
group by是否能用索引呢?有时做个group by把数据分组,接着用count、sum之类的聚合函数做聚合统计。
假设执行类似
select count(*) from table group by xx
看起来必须把你所有的数据放到一个临时磁盘文件里还有加上部分内存,去搞一个分组,按照指定字段的值分成一组一组的,接着对每一组都执行一个聚合函数,这个性能也是极差的,因为毕竟涉及大量的磁盘交互。
因为索引树默认按指定的一些字段都排序好的,字段值相同的数据都是在一起的,若走索引去执行分组后再聚合,那性能一定比临时磁盘文件好多了。
所以一般对于group by后的字段,最好也是按联合索引里的最左侧字段开始,按序排列,这样就能完美利用索引直接提取一组组数据,然后针对每组数据,执行聚合函数。
这group by和order by利用索引的原理和条件差不多,本质都是在group by和order by之后的字段顺序和联合索引中的从最左侧开始字段顺序一致,然后就能利用索引树里已排序的特性,快速根据排序好的数据执行后续操作了。
这就无需针对杂乱数据利用临时磁盘文件加上部分内存数据结构进行耗时耗力的现场排序和分组,那真是速度慢,性能差。
平时设计表里的索引的时候,必须充分考虑到后续你的SQL语句要怎么写,大概会根据哪些字段来进行where语句里的筛选和过滤?大概会根据哪些字段来进行排序和分组?考虑好后,就能为表设计两三个常用的索引,覆盖常见的where筛选、order by排序和group by分组的需求,保证常见的SQL语句都可以用上索引,这样你真正系统跑起来,起码是不会有太大的查询性能问题。
毕竟只要你所有的查询语句都可以利用索引来执行,那么速度和性能通常都不会太慢。如果查询还是有问题,那就要深度理解查询的执行计划和执行原理了,然后基于执行计划来进行深度SQL调优。
然后对于更新语句而言,其实最核心的就是三大问题:
- 索引别太多,索引太多了,更新的时候维护很多索引树肯定是不行
- 可能会涉及到一些锁等待和死锁的问题
- 可能会涉及到MySQL连接池、写redo log文件之类问题
- 点赞
- 收藏
- 关注作者
评论(0)