mysql筆記系列 十四 orderby的原理

2021-10-04 02:55:08 字數 1454 閱讀 8300

語句:select city,name,age from t where city=『杭州』 order by name limit 1000 ;

city為普通索引列。

用explain 命令檢視執行計畫的時候,可以在extra欄位看到 usingfilesort , 當出現這個的時候,就說明需要排序。

mysql會給個執行緒分配乙個記憶體用於排序,這個記憶體叫sort_buffer。

排序是在server層的執行器完成的。

具體過程如下:

1.初始化sort_buffer,然後確定是放city,name,age 這三個字段。

2.根據索引city='杭州』找到第乙個符合條件的主鍵id,然後從根據主鍵id去主鍵索引上找到資料記錄,然後取出其中city,name,age三個字段,

存入到sort_buffer中。

3.再從索引city中取下乙個符合條件的主鍵id。

重複2 3 直到沒有符合條件的資料為止。

4.在sort_buffer中,對資料按照city列進行快速排序

5.對排完序之後的取前1000條 返回。

以上有兩個問題

1.要放的字段很長怎麼辦?比如說 select 後面幾十個列,總不能都放到sort_buffer裡面去。

當mysql判斷出欄位很長的時候,就不會放所有字段,而是放id 和要排序的字段。

這樣在最後排完序之後,再根據排序結果中的id順序去主鍵索引中再查一次,把資料查出來,這種叫rowid排序。

將字段列都放進去的叫全欄位排序。

2.sort_buffer不夠大怎麼辦?

如果符合條件的資料有很多,sort_buffer不夠用,那麼就會觸發外部排序,使用臨時檔案輔助。

將資料按照sort_buffer大小 分成多個檔案,每個檔案依次讀入到sort_buffer 進行快速排序。

最終得到有序的n個檔案

然後依次對這n個檔案依次讀入1個資料到sort_buffer中 再次排序。最終得到乙個排序完的大檔案。

這個是歸併排序

有些場景是用的優先佇列排序(堆排序),這種可以只用排序前1000個,歸併排序是排完了所有的資料。

使用sortbuffer進行堆排序的前提是 sortbuffer能裝得下這個堆,比如說這裡,要維護乙個1000個資料大小的堆。

如果可以就行。

外部排序是很耗費效能的,因此應該盡量避免。

這裡的解決方案是將索引設定成(city,name) ,這樣索引本身就是有序的,取出來的資料就是有序的,就不需要經過排序了。

但是注意

select * from t where city in (「杭州」," 蘇州 ") order by name limit 100; 如果是這樣,即使將索引設定成(city,name)

也不能避免排序,因為索引是先按city排序,如果city相同再按name排,那麼如果限制了city取特定的兩個城市

那麼取出來的這兩個城市的name放在一起, 就不是有序的了。

MySQL中select語句使用order按行排序

本文介紹mysql資料庫中執行select查詢語程式設計客棧句,並對查詢的結果使用order by 子句進行排序。再來回顧一下sql語句中的select語句的語法 selessqbhirroct 語句的基本語法 select 列的集合 from 表名 where 條件 order by 排序欄位和方...

Redis系列 安全(十四)

我們可以通過 redis 的配置檔案設定密碼引數,這樣客戶端連線到 redis 服務就需要密碼驗證,這樣可以讓你的 redis 服務更安全。我們可以通過以下命令檢視是否設定了密碼驗證 127.0 0.1 6379 config getrequirepass1 requirepass 2 預設情況下 ...

MySQL學習 十四

utf8的bom問題 在xp下,用記事本建立utf8檔案的時候,前面多了3個位元組,這3個位元組不用來顯示,是用來辨識編碼用的,ef bb bf告訴記事本,這是utf8編碼。儲存引擎和事務簡單介紹 引擎是mysql儲存資料的不同方式。myisam不支援事務,innodb支援事務 事務應該具有的4個屬...