如何優化sql中的orderBy語句?下面本篇文章給大家介紹一下優化sql中orderBy語句的方法,具有很好的參考價值,希望對大家有所幫助。

程序員必備接口測試調試工具:立即使用
Apipost = Postman + Swagger + Mock + Jmeter
Api設計、調試、文檔、自動化測試工具
后端、前端、測試,同時在線協作,內容實時同步
在使用數據庫進行數據查詢時,難免會遇到基于某些字段對查詢的結果集進行排序的需求。在sql中通常使用orderby語句來實現。將需要排序的字段放到 該關鍵詞后,如果有多個字段的話,就用","分割。
select * from table t order by t.column1,t.column2;
上面的sql表示查詢表table中數據,然后先按照column1排序,如果column1相同的話,在按照column2排序,排序的方式默認是降序。當然排序方式也是可以指定的。在被排序字段后添加 DESC,ASE,分別表示降序和升序。
使用該orderby可以很方便的實現日常的排序操作。使用的多了,不知道你有沒有遇到過這種場景:有時候使用orderby后,sql執行效率非常慢,有時候卻比較快,由于整天被curd纏身,也沒有時間研究,反正就是覺得很神奇。趁這個周末比較閑,就來研究下,mysql中orderby是怎么實現的。
為了方便描述,我們先建立一個數據表 t1,如下:
CREATE TABLE `t1` ( `id` int(11) NOT NULL not null auto_increment, `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL, PRIMARY KEY (`id`) , KEY `a` (`a`) USING BTREE ) ENGINE=InnoDB;
并插入數據:
insert into t1 (a,b,c) values (1,1,3); insert into t1 (a,b,c) values (1,4,5); insert into t1 (a,b,c) values (1,3,3); insert into t1 (a,b,c) values (1,3,4); insert into t1 (a,b,c) values (1,2,5); insert into t1 (a,b,c) values (1,3,6);
為了使索引生效,插入10000行 7,7,7,無關數據,數據量少的情況下,會直接全表掃描
insert into t1 (a,b,c) values (7,7,7);
我們現在需要查找 a=1的所有記錄,然后按照b字段進行排序。
查詢sql為
select a,b,c from t1 where a = 1 order by b limit 2;
為了防止在查詢過程中全表掃描,我們在字段a上添加了索引。
首先我們先通過語句
explain select a,b,c from t1 where a = 1 order by b lmit 2;
查看sql的執行計劃,如下所示:

在extra中我們可以看到出現了Using filesort,這個表示 該sql執行過程中,執行了排序操作,排序操作在 sort_buffer中完成,sort_buffer是mysql分配給每個線程的一個內存緩沖區,該緩沖區專門用來完成排序,大小默認是1M,其大小由變量 sort_buffer_size 進行控制。
mysql在對orderby進行實現時,根據放入到sort_buffer中的字段內容不同,進行了兩種不同實現方式:全字段排序和rowid排序。
全字段排序
首先我們先通過一張圖整體看一下sql執行過程:

mysql先根據查詢條件確定需要排序的數據集,也就是表中 a=1的數據集,即主鍵id從1到6的這些記錄。
整個sql的執行的過程如下:
1.創建并初始化sort_buffer,并確定需要放到該緩沖區中的字段,也就是a,b,c這三個字段。
2.從索引樹a中找到第一個滿足a=1的主鍵id,也就是id=1。
3.回表到id索引,取出整行數據,然后從整行數據中,取出a,b,c的值,放入到sort_buffer中。
4.從索引a中按照順序找到下一個a=1的主鍵id。
5.重復步驟3和步驟4,直到獲取到最后一個a=1的記錄,也就是主鍵id=5。
6.此時滿足條件a=1的所有記錄的 a,b,c字段,全部讀放到了sort_buffer中,然后,對這些數據按照b的值進行進行排序,排序的方式是快速排序。就是那個面試經常面到的快速排序,時間復雜度為log2n的快速排序。
7.然后從排序后的結果集中取出前2行數據。
上面是就是msql中orderby的執行流程。因為放入到sort_buffer中的數據是需要輸出的全部字段,所以這種排序被稱為全排序。
看到這里不知道你是否會有疑問?如果需要排序的數據量很大的話,sort_buffer裝不下怎么辦?
的確,如果a=1的數據行特別多,且需要存放到sort_buffer中的字段比較多,可能不止a,b,c三個字段,有些業務可能需要輸出
站長資訊網