優化 ORDER BY 語句

2021-10-06 20:14:12 字數 3021 閱讀 3861

一、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...