MySQL的兩種filesort演算法介紹以及相關引數的設定和優化
一.filesort演算法介紹
MySQL有兩種filesort演算法:two-pass和single-pass。
(1).two-pass
列長度之和超過max_length_for_sort_data位元組時就使用這個演算法,其原理是:先按照where篩選條件讀取資料行,並儲存每行的排序欄位和行指標到排序緩衝區(sort buffer)。如果排序緩衝大小不夠,就在記憶體中執行一個快速排序操作,把排序結果儲存到一個臨時檔案裡,
用一個指標指向這個已經排序好了的塊,然後繼續讀取資料,直到所有行都讀取完畢為止。這是第一次讀取記錄。以上第一次讀取記錄時,可以按照索引排序或表掃描,可以做到順序讀取。但第二次讀取記錄時,雖然排序欄位是有序的,行快取裡儲存的行指標是有序的,
但所指向的物理記錄需要隨機讀,所以這個演算法可能會帶來很多隨機讀,從而導致效率很低。
優點是:排序的資料量小,一般在記憶體裡即可完成。
缺點是:需要讀取記錄兩次,第二次讀取時候可能會產生許多隨機IO,成本可能會比較高。
(2).single-pass
MySQL一般使用這種演算法。其原理是:按照篩選條件把SQL中涉及的欄位全部讀入排序緩衝區(sort buffer)裡,然後依據排序欄位進行排序,
如果排序緩衝不夠,會將臨時排序結果寫入到一個臨時檔案裡,最後合併臨時排序檔案,直接返回已經排序好的結果集.
優點是:不需要讀取記錄兩次,相對於two-pass,可以減少I/O開銷。
缺點是:由於要讀入所有欄位,排序緩衝可能不夠,需要額外的臨時檔案協助進行排序,導致增加額外的I/O成本。
二.排序相關的引數設定和優化
相關引數如下:
max_length_for_sort_data:如果各列長度之和(包括選擇列、排序列)超過了max_length_for_sort_data位元組,那麼就使用two-pass演算法。
如果排序BLOB、Text欄位,使用的也是two-pass演算法,那麼這個值設定的太高會導致系統I/O上升和CPU下降,所以建議不要將max_length_for_sort_data
的值設定的太高。
max_sort_length:如果排序BLOB、TEXT欄位,則僅排序前max_sort_length個位元組。
可以考慮的優化方向如下:
(1).增大sort_buffer_size
一般情況下使用預設的single-pass演算法即可。可以考慮增大sort_buffer_size以減少磁碟I/O。
需要留意的是欄位長度之和不要超過max_length_for_sort_data,只查詢所需要的列,注意列的長度和型別。 MySQL目前讀取和計算列的長度是按照定義的最大的度進行的,所以在設計表結構的時候,不要將varchar型別的欄位設定得過大,雖然對於varchar型別來說,在物理磁碟中實際
儲存可以做到緊湊,但在排序的時候是會分配最大定義長度的,有時候排序階段所產生的臨時檔案甚至比原始表還要大。MySQL 5.7版本在這方面做了一些優化。
(2).對於two-pass演算法,可以考慮增大read_rnd_buffer_size,但由於這個全域性變數是對所有連線都生效,因此建議只在會話級進行設定,以加速一些特殊的大操作。
(3).在作業系統層面,優化臨時檔案的讀寫。
MySQL有兩種filesort演算法:two-pass和single-pass。
(1).two-pass
列長度之和超過max_length_for_sort_data位元組時就使用這個演算法,其原理是:先按照where篩選條件讀取資料行,並儲存每行的排序欄位和行指標到排序緩衝區(sort buffer)。如果排序緩衝大小不夠,就在記憶體中執行一個快速排序操作,把排序結果儲存到一個臨時檔案裡,
用一個指標指向這個已經排序好了的塊,然後繼續讀取資料,直到所有行都讀取完畢為止。這是第一次讀取記錄。以上第一次讀取記錄時,可以按照索引排序或表掃描,可以做到順序讀取。但第二次讀取記錄時,雖然排序欄位是有序的,行快取裡儲存的行指標是有序的,
但所指向的物理記錄需要隨機讀,所以這個演算法可能會帶來很多隨機讀,從而導致效率很低。
優點是:排序的資料量小,一般在記憶體裡即可完成。
缺點是:需要讀取記錄兩次,第二次讀取時候可能會產生許多隨機IO,成本可能會比較高。
(2).single-pass
MySQL一般使用這種演算法。其原理是:按照篩選條件把SQL中涉及的欄位全部讀入排序緩衝區(sort buffer)裡,然後依據排序欄位進行排序,
如果排序緩衝不夠,會將臨時排序結果寫入到一個臨時檔案裡,最後合併臨時排序檔案,直接返回已經排序好的結果集.
優點是:不需要讀取記錄兩次,相對於two-pass,可以減少I/O開銷。
缺點是:由於要讀入所有欄位,排序緩衝可能不夠,需要額外的臨時檔案協助進行排序,導致增加額外的I/O成本。
二.排序相關的引數設定和優化
相關引數如下:
max_length_for_sort_data:如果各列長度之和(包括選擇列、排序列)超過了max_length_for_sort_data位元組,那麼就使用two-pass演算法。
如果排序BLOB、Text欄位,使用的也是two-pass演算法,那麼這個值設定的太高會導致系統I/O上升和CPU下降,所以建議不要將max_length_for_sort_data
的值設定的太高。
max_sort_length:如果排序BLOB、TEXT欄位,則僅排序前max_sort_length個位元組。
可以考慮的優化方向如下:
(1).增大sort_buffer_size
一般情況下使用預設的single-pass演算法即可。可以考慮增大sort_buffer_size以減少磁碟I/O。
需要留意的是欄位長度之和不要超過max_length_for_sort_data,只查詢所需要的列,注意列的長度和型別。 MySQL目前讀取和計算列的長度是按照定義的最大的度進行的,所以在設計表結構的時候,不要將varchar型別的欄位設定得過大,雖然對於varchar型別來說,在物理磁碟中實際
儲存可以做到緊湊,但在排序的時候是會分配最大定義長度的,有時候排序階段所產生的臨時檔案甚至比原始表還要大。MySQL 5.7版本在這方面做了一些優化。
(2).對於two-pass演算法,可以考慮增大read_rnd_buffer_size,但由於這個全域性變數是對所有連線都生效,因此建議只在會話級進行設定,以加速一些特殊的大操作。
(3).在作業系統層面,優化臨時檔案的讀寫。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15498/viewspace-2135906/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【MYSQL】兩階段提交及相關引數介紹MySql
- SolrCloud相關概念和兩種路由演算法介紹SolrCloud路由演算法
- MySQL中的統計資訊相關引數介紹MySql
- MySQL change buffer介紹和相關引數調整建議MySql
- 幾個和MySQL InnoDB相關的引數設定說明MySql
- linux的vm相關引數介紹Linux
- MySQL的幾個和innodb相關的主要引數設定總結MySql
- 優化mysql的效能,詳細介紹Mysql的配置my.cnf的引數優化MySql
- Oracle的AMM和ASMM以及相關引數探究OracleASM
- Redis持久化的兩種方式的優缺點介紹Redis持久化
- redis兩種持久化方式的優缺點介紹Redis持久化
- Oracle查詢優化器的相關引數Oracle優化
- Oracle優化相關的一些引數Oracle優化
- Hive優化相關設定Hive優化
- Code::Blocks 編譯引數的相關設定BloC編譯
- 介紹幾種提高mysql的效能和對於sql的優化的方法MySql優化
- Redis學習 RDB和AOF兩種持久化介紹以及實現Redis持久化
- 設計模式的相關介紹設計模式
- 介紹兩個好玩的和Github相關的Chrome擴充套件GithubChrome套件
- Oracle 優化引數 optimizer_mode 介紹Oracle優化
- oracle 安裝相關引數設定Oracle
- mysql一些引數的介紹MySql
- 【SQL 效能優化】引數設定SQL優化
- MySQL效能相關引數MySql
- Mysql的優化的相關知識MySql優化
- Linux核心優化之TCP相關引數Linux優化TCP
- 兩個引數設定
- Mysql資料庫的join演算法介紹,優美的執行優化MySql資料庫演算法優化
- MySQL 連線相關引數MySql
- MySQL slow log相關引數MySql
- [轉帖]Redis相關的核心引數解釋與設定Redis
- 介紹tomcat Connector 引數優化說明Tomcat優化
- MySQL各種日誌的簡介和設定方法MySql
- 連線MySQL資料庫的兩種方式介紹MySql資料庫
- MySQL 索引優化 Using where, Using filesortMySql索引優化
- mvn相關介紹和命令
- MySQL binlog三種格式的優缺點和修改方法介紹MySql
- MySQL引數配置優化MySql優化