Mysql里的order by與索引


Mysql索引的建立對於Mysql的高效運行是很重要的,索引可以大大提高MySQL的檢索速度。大家在使用Mysql的過程中,肯定都使用到了索引,也都知道建立索引的字段通常都是作為查詢條件的字段(一般作為WHERE子句的條件),卻容易忽略查詢語句里包含order by的場景。其實涉及到排序order by的時候,建立適當的索引能夠提高查詢效率。這里就介紹一下利用索引優化order by的查詢語句。

創建測試數據

創建一張測試數據表user_article(用戶文章表),有id(主鍵),user_id(用戶ID),title(標題),content(內容),comment_num(評論次數),create_time(創建時間)字段。

CREATE TABLE IF NOT EXISTS `user_article`(
   `id` INT UNSIGNED AUTO_INCREMENT,
   `user_id`  INT UNSIGNED,
   `title` VARCHAR(100) NOT NULL,
   `content`  VARCHAR(255) NOT NULL,
   `comment_num`  INT UNSIGNED,
   `create_time`  INT UNSIGNED, 
   PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

插入測試數據,插入數據多一點,如果數據少mysql會認為走索引效率低,全表掃描效率高:

insert into user_article (user_id,title,content,comment_num,create_time) values(1,'標題1','內容1',10,1582289251);
insert into user_article (user_id,title,content,comment_num,create_time) values(2,'標題2','內容2',20,1582634851);
insert into user_article (user_id,title,content,comment_num,create_time) values(3,'標題3','內容3',30,1582634851);
insert into user_article (user_id,title,content,comment_num,create_time) values(1,'標題4','內容4',40,1584276451);

where+單字段order by

形如SELECT [column1],[column2],…. FROM [TABLE] WHERE [columnX] = [value] ORDER BY [sort]

explain select * from user_article where user_id=10000 order by comment_num desc;

結果:

查詢未使用索引,可建立一個聯合索引(user_id,comment_num)來優化。

create index a on user_article(user_id,comment_num);
show index from user_article;
explain select * from user_article where user_id=10000 order by comment_num desc;

結果:

查詢已經使用了建立的索引,如果只對user_id建立索引,會是什么情況呢?

drop index a on user_article;
create index user_id on user_article(user_id);
show index from user_article;
explain select * from user_article where user_id=10000 order by comment_num desc;

結果:

查詢同樣使用了索引,區別在於extra里多了using filesort,多了排序操作,查看執行時間,聯合索引的查詢效率高於單索引,不對user_id建立索引,只對comment_num建立索引會是什么情況呢?

drop index user_id on user_article;
create index comment_num on user_article(comment_num);
show index from user_article;
explain select * from user_article where user_id=10000 order by comment_num desc;

結果:

如果對where條件字段未建索引,只對排序字段建索引,是不會使用索引的。

where+多字段order by

形如SELECT * FROM [table] WHERE uid=1 ORDER x,y

create index b on user_article(user_id,comment_num,create_time);
explain select * from user_article where user_id=10000 order by comment_num,create_time;

結果:

建立索引(user_id,comment_num,create_time)實現order by的優化,只對user_id建立索引,與單字段order by一樣,會使用索引,但是查詢效率不及聯合索引。

從上面測試可以看出,走不走索引還是跟where條件里的字段是否建立索引有關,如果where條件里字段未建立索引,那查詢不會使用索引,建立聯合索引,減少了using_filesort的排序操作,可以提高查詢效率。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM