mysql order by排序深入理解

2021-09-02 12:22:17 字數 1509 閱讀 3476

mysql 排序篇

mysql 排序,如果從比較深入的角度來討論這個命題,這一節完全可以出一本書。在這裡我們只做簡單介紹。

mysql排序,這個動作會出現在兩個兩個地方,乙個是記憶體,另乙個是磁碟檔案。由關鍵字order by 驅動。具體的排序條件根據結果集的字段決定。

1 mysql 排序的演算法

mysql 的排序演算法分為兩種,一種是單路排序,一種是雙路排序。

雙路排序: 按照sql指定的條件將符合的資料從磁碟中讀取出來,把每一條資料參與排序的列以及這一行資料在磁碟中的位置(row point 又叫指標資訊)

丟給緩衝區,就是sort buffer. 在緩衝區中完成排序,之後將排序結果丟給隨機讀取緩衝區(read_rnd_buffer),隨機讀取緩衝區根據指標資訊再到磁碟中讀取該行資料的

其他資訊,之後再將合併結果返回給客戶端。

很明顯 這種排序方法產生了兩次io操作。

單路排序: 按照sql指定的條件將符合的資料從磁碟中全部讀取出來,之後丟給緩衝區sort buffer ,緩衝區根據使用者指定的排序條件完成排序,將結果返回給客戶端。

這種排序方式是在mysql 4.1之後出現的,選擇單路排序需要一定條件。

相比之下,單路排序比雙路排序確實減少了io次數,降低了磁碟開銷,但是這裡必須提出,減少io操作的代價是增加了記憶體消耗。這是典型的用空間換時間的

例子。我們如何讓mysql使用單路排序呢?

1 查詢語句所取出的字段型別大小總和要小於 max_length_for_sort_data。

2 排序欄位中不包含text和blob型別。

2 order by 的實現與優化

還是那句話,良好的效能多取決於良好的設計,尤其是schema的早期設計。不要寄希望於後期的所謂的優化或者重構,那會讓你痛苦。

schema設計,盡可能把頻繁訪問的屬性和冷屬性分離,盡可能把小屬性和大屬性存放在不同的表裡。去除不需要的業務設計,這會增加伺服器負擔。

在設計sql語句的時候,你需要小心仔細,必須想象你的sql處理的是較大資料規模的情況,明確知道應用程式和mysql各自的優劣,比如mysql擅長表之間的join操作,而且這已經被

mysql的開發者們優化的非常好,那麼你就讓mysql處理表之間的join,應用程式對於一些複雜計算和邏輯關係的處理表現的輕鬆自如,那麼你就應該讓mysql避免這一塊。

mysql忌諱大範圍的磁碟io,或者頻度非常高的io操作,那麼排序就盡可能的利用索引,完善的索引設計也是高效能的保證。排序的過程中盡可能使用索引字段作為order by的條件。

明白小結果集驅動大結果集的道理。這一點很重要。select 一定要去除不必要返回的資料,忌諱select *,因為你不需要,如果不得不返回你這次查詢根本不需要的資料,那麼請

重新審查你的schema設計。不要盲目增大 max_length_for_sort_data 字段,這樣會使mysql 不得不將資料分成很多段然後進行排序。為了減少使用臨時表,我們可以適當增大

sort buffer size這個引數的大小,這樣可以在排序過程中減少對資料的分段。

mysql order by 排序技巧

首先我們新建表test,如下 create table test id int 11 not null auto increment,name varchar 255 default null,primary key id engine innodb auto increment 7 default...

mysql order by 排序索引

接手別人的 遇到乙個客戶需求,說介面查詢較慢,需要進行優化。後面通過列印執行時間定位到是某一句sql執行較慢。sql如下 select from t base alarm tba where1 1and tba.rule type 1order by alarm status asc end ts ...

Mysql order by 多欄位排序

降序desc 由大到小 公升序asc 由小到大 mysql單個字段降序排序 select from table order by id desc mysql單個字段公升序排序 select from table order by id asc mysql多個字段排序 select from tabl...