一、mysql 中兩種排序方式
1) 第一種通過有序索引順序掃瞄直接返回有序資料,這種方式在使用 explain 分析查詢的時候顯示為 using index (即通過索引列就能返回所需要的資料),不需要額外的排序,操作效率較高。
mysql> explain select customer_id from customer order by store_id \g;
*************************** 1. row ***************************
id: 1
select_type: ******
table: customer
partitions: null
type: index
possible_keys: null
key: idx_fk_store_id
key_len: 1
ref: null
rows: 599
filtered: 100.00
extra: using index
1 row in set, 1 warning (0.01 sec)
2) 第二種是通過返回資料進行排序,即 filesort 排序,所有不是通過索引直接返回排序結果的排序都叫 filesort 排序。filesort 排序是使用磁碟檔案還是臨時表取決於 mysql 伺服器對排序引數的設定和需要排序資料的大小。
mysql> explain select * from customer order by store_id \g;
*************************** 1. row ***************************
id: 1
select_type: ******
table: customer
partitions: null
type: all
possible_keys: null
key: null
key_len: null
ref: null
rows: 599
filtered: 100.00
extra: using filesort
1 row in set, 1 warning (0.00 sec)
filesort 是通過相應的排序演算法,將取得的資料在 sort_buffer_size 系統變數設定的記憶體排序區中排序,如果記憶體裝載不下,它就會將磁碟上的資料進行分塊,再對各個資料塊進行排序,然後將各個塊合併成有序的結果集。 sort_buffer_size 設定的排序區是每個執行緒獨佔的,所以同一時刻, mysql 中存在多個 sort buffer 排序區。
二、優化方法
儘量減少額外的排序,通過索引直接返回有序資料。 where 條件和 order by 使用相同的索引,並且 order by 的順序和索引順序相同,並且 order by 的字段都是公升序或者降序,否則肯定需要額外的排序操作,這樣就會出現 filesort 。
1)下列情況 sql 可以使用索引
select * from tabname order by key_part1,key_part2,...;
select * from tabname where key_part1=1 order by key_part1 desc,key_part2 desc;
select * from tabname order by key_part1 desc,key_part2 desc;
2)以下幾種情況下不使用索引
1) order by 的字段混合 asc 和 desc
select * from tabname order by key_part1 desc,key_part2 asc;
2)用於查詢的關鍵字與 order by 中所使用的不相同
select * from tabname where key2=constant order by key1;
3)對不同的關鍵字使用 order by
select * from tabname order by key1,key2;
三、filesort 排序演算法
1、對於 filesort ,mysql 有兩種排序演算法。
1)兩次掃瞄演算法(two passes):首先根據條件取出排序欄位和行指標資訊,之後在排序區 sort buffer 中排序。如果排序區 sort buffer 不夠,則在臨時表 temporary table 中儲存排序結果。完成排序後根據行指標回表讀取記錄。這種演算法需要兩次訪問資料,第一次獲取排序欄位和行指標資訊,第二次根據行指標獲取記錄,尤其第二次讀取操作可能導致大量隨機 i/o 操作,優點是排序的時候記憶體開銷較少。
2)一次掃瞄演算法(single pass):一次性取出滿足條件的行的所有字段,然後在排序區 sort buffer 中排序後直接輸出結果集。排序的時候記憶體開銷比較大,但是排序效率比兩次掃瞄演算法要高。
2、注意
1)max_length_for_sort_data > query 語句取出的字段總大小,使用一次掃瞄演算法,反之使用兩次掃瞄演算法。
2)適當加大系統變數 max_length_for_sort_data 的值,能夠讓 mysql 選擇更優化的 filesort 排序演算法。當然 max_length_for_sort_data 設定過大會造成 cpu 利用率過低和磁碟 i/o 過高。
3)適當加大 sort_buffer_size 排序區,盡量讓排序在記憶體中完成,而不是通過建立臨時表放在檔案中進行;當然也不能無限制加大 sort_buffer_size 排序區,因為 sort_buffer_size 引數是每個執行緒獨佔的,設定過大,會導致伺服器 swap 嚴重,要考慮資料庫活動連線數和伺服器記憶體的大小來適當設定排序區。
4)盡量只使用必要的字段,select 具體的欄位名稱,而不是 select * 選擇所有字段,這樣可以減少排序區的使用,提高 sql 效能。
優化orderby語句
資料庫排序在很多業務系統都有這方面的硬性要求,但是很多情況下大資料表的排序查詢很是緩慢,查了下資料,現在總結如下 可以適當調大 sort area size 的值 10240000 10m alter system set sort area size 10240000 scope spfile 在...
MySQL優化order by語句
優化order by語句 mysql的兩種排序方式 1.第一種就是通過有序索引順序掃瞄直接返回資料,常見的是使用explain分析查詢extra顯示using index,這種情況不需要額外的排序,高效率。2.通過返回資料進行排序,通常是使用explain分析查詢語句使用extra表示filesor...
MySQL 優化 ORDER BY 優化
本文翻譯自mysql 官網 order by optimization,mysql 版本 5.7。這一部分描述了mysql何時會使用索引來滿足order by子句,filesort 操作會在索引不能生效的時候被用到,以及優化器對order by的執行計畫資訊。order by後面有沒有跟著limit...