MySQL性能优化(二)优化排序操作
排序是数据库的基本功能。
一个例子
SELECT * FROM audit_log WHERE user_id = xxx AND log_type = ‘xxxx’ ORDER BY gmt_create DESC
执行计划
看这里的执行计划:
key: idx_userid_logtype。使用了idx_userid_logtype索引。
key_len: 8。user_id为bigint
ref: const。
Extra: Using where; Using filesort。因为SQL中用到了order by,这里使用了filesort。
排序是一个耗资源的操作,需要消耗CPU和内存资源。如果需要排序的数据量超过了排序内存,需要将数据写入磁盘文件,进行多趟排序。
在上面这个例子中,我们可以利用索引的有序性来避免排序。这也是优化排序SQL的一个常用的方法。
使用索引消除排序
alter table audit_log drop key idx_userid_logtype, add KEY `idx_userid_logtype` (`user_id`,`log_type`,`gmt_create`)
我们在索引中加入gmt_create字段,再查看执行计划:
可以看到,Extra中没有了filesort相关内容。
前提条件
使用索引消除排序有几个前提条件:
1、排序字段前面的字段(这里是user_id, log_type),都需要以等值条件传入到where条件中(user_id=xx and log_type=xx)。
2、如果根据多个字段排序( order by col_1, col_2),则索引中相关字段也要以同样的顺序( index idx(col_1, col_2)
对于上述索引(user_id, log_type, gmt_create),下面的SQL就无法使用索引来消除排序。还是需要filesort。
SELECT * FROM audit_log WHERE user_id = xxx ORDER BY gmt_create DESC