mysql是怎麼操作order by來進行排序的
mysql的排序用到了sort buffer,sort buffer是一個內存塊。
mysql會先取出需要排序的數據,然後把數據放入sort buffer,當所有數據都放入sort buffer或者sort buffer滿了就開始排序,然後將排序好的結果返回給客戶端。
參數sort_buffer_size
顯示的就是sort buffer的大小。
如果數據量超過sort buffer,那麼就會通過磁盤臨時文件輔助進行排序,如果數據量比較小,則可以直接在內存中進行。
在內存中排序會使用快排算法
,而通過磁盤臨時文件則會使用歸併排序算法
。
排序步驟可以分爲以下幾步:
- 取出select的數據存入sort buffer。
- 在sort buffer中進行快排或者歸併排序算法。
- 如果有limit按照limit取相應的結果集進行返回。
rowid排序算法
這裏面select出來的數據量可能會很大,跟你要查詢的列多少有關,如果你的列很多,那麼mysql可能會使用另外一種排序方法,叫做rowid
排序。
rowid算法不管你查詢出來的結果集,它只把必要的字段放入sort buffer中,這樣sort buffer就可以存入更多的數據來進行排序。
必要的字段也就是你排序需要的字段和主鍵字段,比如order by time
那麼他只會放入id 和 time,然後按照time字段排序完成後再通過主鍵id回表查詢一遍數據,然後返回數據。
顯然rowid算法還需要再次回表,所以效率上要低一些,所以不是mysql默認使用的排序方法。
只有當你的內存不夠用,查詢的列太多的時候,mysql纔會使用這種算法。
排序步驟可以分爲以下幾步:
- 取出排序的字段和id存入sort buffer。
- 在sort buffer中進行快排或者歸併排序算法。
- 按照排序結果和limit數量回表查詢然後返回數據。
不需要排序的方法
既然這樣,我們爲了更快速,可以避免mysql排序。
innoDB的索引是有序的,也就是說,如果我們要排序的字段本身就是有序的,那麼就不用排序了。
所以我們可以在排序字段上建立索引,而如果我們查詢的字段不多,甚至可以建立覆蓋索引,那麼速度會快很多。
mysql到底有沒有進行排序,可以通過explain的執行計劃來看。如果最後有using filesort,就表示使用了排序算法。