MySQL filesort优化案例一则(二)

2014-11-24 15:43:43 · 作者: · 浏览: 2
x(idx_status_rate_release) WHERE `status`='Y' and releaseTime > '2013-07-08 11:00:00' ORDER BY rate DESC LIMIT 0, 10; +----+-------------+-----------+------+-------------------------+-------------------------+---------+-------+---------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-----------+------+-------------------------+-------------------------+---------+-------+---------+-------------+ | 1 | SIMPLE | tbxxxxxx | ref | idx_status_rate_release | idx_status_rate_release | 1 | const | 1057094 | Using where | +----+-------------+-----------+------+-------------------------+-------------------------+---------+-------+---------+-------------+ 1 row in set (0.00 sec)

从执行计划可以看出, 此时没有了filesort这个阶段,因为默认status, rate这个索引前缀就是按照rate来排序的,因此正好可以利用索引的数据有序来达到最终的order by rate效果。细心的朋友可能会发现在这个执行计划中估算扫描的行数是上一个执行计划的2倍, 多扫描这么多行开销不大吗(这也是为什么当初第一反应优化这条SQL时会考虑优化索引来减少扫描的行数)? 事实上证明这个开销相对于filesort来说已经很小,有两点可以证明:profile的分析显示99%的时间是耗在sorting result,第二,在线上一个从库上测试第二个执行计划查询时间为0.1s左右,而第一个执行计划的查询时间在3s左右。虽然说一般来说并不建议使用use index这种语法,后期的不确定性较大,但是既然提供这种语法就有它自己的理由, 用好了自然有优势,先这么将就着吧。另外这里需要说明的是:(status, rate, releaseTime)这个索引中只有rate是必须得, status由于只有两个取值,筛选效果很不明显, releaseTime用不到(ICP后可能能用到)
最后是两点小感悟:1.MySQL的优化器还是那么有点坑爹, 有时候不靠谱。2.有时候优化一个SQL还是不能完全凭直觉,平常的经验,profile这种命令可以完全将一个SQL查询执行过程中各个阶段的开销都统计出来,这样我们就有了针对一个SQL的优化关键点,这样才能做不到不盲目,从而高效快速的优化。