天天看點

MySQL - order by排序優化

排序優化:order by(索引不再用于查詢,而是用于排序了)(order by預設升序)

一句話:索引建的好,對order by的語句也有影響,怎麼看這個關于order by的語句建立的好不好:根據Explain中Extra列是否顯示Using filesort(顯示了就不好)

Using index(掃描有序索引排序) 和 Using filesort(檔案排序),前者好,後者意味着order by 的列名(個數、順序、種類)有些問題。

Using filesort時,就沒有使用索引提供好的順序,而是自己又進行了一次排序,這種排序有兩種算法:

1.雙路排序

使用在MYSQL4.1之前,掃描磁盤(IO)兩次:根據行指針,第一次掃出order by的列名的指,排序,第二次再根據排好的順序所對應的行指針,在磁盤裡進行掃描,以輸出結果。

2.單路排序

MySQL - order by排序優化

但是單路排序也有出問題的時候,這個時候就會偷雞不成蝕把米:

即sort_buffer不夠用的時候(裡面存的是待排序的很多行完整的資料)。

解決辦法(MYSQL伺服器的參數調優):

1.提高sort_buffer_size參數設定提高;(指緩存的總容量)

2.max_length_for_sort_data參數設定;(指每行資料的最大上限)

(即這兩者共同制約,決定使用哪種排序算法:雙路or單路)

3.少用select *(因為查出的所有東西(每行的完整資料)都會放心buffer裡,select *就很可能快速把buffer撐爆)

MySQL - order by排序優化

即如果排序(order by) 和 查詢(where) 使用了相同索引,就不會出現Using filesort。

但是要注意的是 是where 和 order by 可以互相結合(而非select的内容 和 order by 互相結合),和select,即你要查什麼毫無關系!

小總結:ORDER BY 子句盡量使用Index方式排序,避免使用FileSort方式排序,盡可能在索引列上完成排序操作,遵照索引鍵的最佳左字首。如果不在索引列上,FileSort有兩種算法,Mysql就要啟動雙路排序和單路排序。

舉例:

此例的一個前提:建立了一個idx_a_b_c的聯合索引

MySQL - order by排序優化

感覺是那個意思,即在where中指定了a為常量(但是當a為範圍時(如 a in(...)、a >1這種),a作為大哥并不好使用,與a=常量完全不一樣!),那麼b、c就可以接在a後面,即此時order by也能夠使用到索引;

注意一下上面的紅框,即這裡也能使用哦~

MySQL - order by排序優化

隻看紅框就夠了:雖然預設order by升序,但是隻要保持一緻,也能索引(即全為顯示設定為降序時,也能使用索引)

最後總結一下:所謂的排序和查詢可以使用相同的索引,這裡的查詢是指where中的列,和select的内容應該是無關的吧:對的!

MySQL - order by排序優化