有時候我們執行MySQL查詢的時候,查詢語句沒有加order by,但是發現結果總是已經按照id排序好了的,難道MySQL就是為了好看給我們排序
如上圖數據,是我查詢了語句
SELECT * from employees WHERE first_name like "be%";
看結果是按照emp_no排序,其中first_name上是有索引的。
首先我們需要搞清楚MySQL回表,回表是指在我們利用的索引樹(比如上述語句用到的first_name字段索引)的數據不能滿足我們select中選中的數據,因為first_name是二級索引(也可以說是非聚簇索引),該索引只能拿到emp_no,first_name字段值,索引select *查詢的話就只能到主鍵索引所在的索引樹上獲取相應數據。
按照上述查詢去first_name索引上匹配的話,我們匹配到的數據肯定是沒法保證按照emp_no排序了,但是為啥最終我們看到的數據是按照emp_no排序了呢?其實這是mysql的mrr機制。
mrr想要達到的目的就是從磁盤的隨機讀變成順序讀,因為如果我們直接拿emp_no亂序的數據回表查詢,那么就是一個隨機讀,這個性能是很差的,所以MySQL會在回表之前提前將emp_no數據排序好,這樣回表就變成了順序讀,極大提高性能。
當我們將mrr關掉
set optimizer_switch='mrr=off';
再次執行
可以看到emp_no已經是亂序了
開啟mrr后,我們來explain該查詢語句,發現extra里顯示了Using MRR
所以當我們期望查詢的結果有序的時候,一定要在查詢的語句中加上自己的order by,而不能因為默認排序了,就不加order by,因為MySQL的機制他是不定的。