此篇文章主要是解决Order by带来Using filesort的问题
1、创建表
CREATE TABLE tblA(
#id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
age INT,
birth TIMESTAMP NOT NULL
);
INSERT INTO tblA(age, birth) VALUES(22, NOW());
INSERT INTO tblA(age, birth) VALUES(23, NOW());
INSERT INTO tblA(age, birth) VALUES(24, NOW());
CREATE INDEX indx_A_ageBirth ON tblA(age, birth);
SELECT * FROM tblA;
2、看如下几组SQL:
(一)
EXPLAIN SELECT * FROM tblA WHERE age > 20 ORDER BY age;
Paste_Image.png
EXPLAIN SELECT * FROM tblA WHERE age > 20 ORDER BY age, birth;
Paste_Image.png
带头大哥age一直在,所以不会产生Using filesort,因为从火车头开始,而order by正好也是从火车头开始,age索引可以用上。
(二)
EXPLAIN SELECT * FROM tblA WHERE age > 20 ORDER BY birth;
EXPLAIN SELECT * FROM tblA WHERE age > 20 ORDER BY birth, age;
Paste_Image.png
带头大哥age不再order by范围内了,前面where条件还是大于号(范围值),索引断了,所以排序的时候无法用到索引,产生了Using filesort
(三)
EXPLAIN SELECT * FROM tblA ORDER BY birth;
EXPLAIN SELECT * FROM tblA WHERE birth > '2011-11-11 11:11:11' ORDER BY birth;
Paste_Image.png
带头大哥age完全没用上
(四)
EXPLAIN SELECT * FROM tblA WHERE birth > '2011-11-11 11:11:11' ORDER BY age;
Paste_Image.png
不难发现,我order by用到了带头大哥age,索引不会产生Using filesort
(五)
EXPLAIN SELECT * FROM tblA ORDER BY age ASC, birth DESC;
EXPLAIN SELECT * FROM tblA ORDER BY age DESC, birth ASC;
Paste_Image.png
(六)
EXPLAIN SELECT * FROM tblA ORDER BY age ASC, birth ASC;
EXPLAIN SELECT * FROM tblA ORDER BY age DESC, birth DESC;
Paste_Image.png
从(五)和(六)可知,排序的话要么都升序,要么都降序,否则mysql内部会不知道怎么排序,排序也是索引的一部分(Btree),所以不一致时会产生Using filesort
(七)
EXPLAIN SELECT * FROM tblA WHERE age = 20 ORDER BY birth;
Paste_Image.png
这就神奇了,居然没有Using filesort,是因为where 条件是个常量,而不是个范围,所以会自动传递到order by,所以order by带头大哥还是age
总结
Paste_Image.png
重要
Paste_Image.png
Group By关键字优化
Paste_Image.png
若有兴趣,欢迎来加入群,【Java初学者学习交流群】:458430385,此群有Java开发人员、UI设计人员和前端工程师。有问必答,共同探讨学习,一起进步!
欢迎关注我的微信公众号【Java码农社区】,会定时推送各种干货:
qrcode_for_gh_577b64e73701_258.jpg











网友评论