《MySQL——order by逻辑(全字段排序与rowid排序)》
創(chuàng)建一個表,然后使用查詢語句:
 查詢城市是“杭州”的所有人名字,并且按照姓名排序返回前 1000 個人的姓名、年齡
它的執(zhí)行流程如下:
全字段排序
為了避免全表掃描,需要在city字段上加上索引
假設滿足city = '杭州’條件的行是從ID_X到ID_(X+N)的這些記錄。
 執(zhí)行流程:
 1、初始化sort_buffer,確定放入name、city、age三個字段;
 2、從索引city找到第一個滿足city = '杭州’條件的主鍵id,也就是ID_X;
 3、到主鍵id索引取出整行,取name、city、age三個字段值,存入sort_buffer;
 4、從索引city取下一個記錄的主鍵id;
 5、重復step3、4直到city的值不滿足查詢條件為止,對應的ID(X+N);
 6、對sort_buffer中的數(shù)據按照字段name做快速排序
 7、按照排序結果取前1000行返回給客戶端
tip:sort_buffer是MySQL分配給每個線程用于排序的內存。
 sort_buffer是MySQL分配給每個線程用于排序的內存。sort_buffer_size是sort_buffer的大小,如果要排序的數(shù)據量小于sort_buffer_size,排序就在內存中完成,如果排序數(shù)據量過大,就得使用磁盤臨時文件輔助排序。外部排序一般使用歸并排序算法。
rowid 排序
全字段排序方法缺點:單行大的話占用內存空間。
 通過修改MySQL中專門控制用于排序的行數(shù)據的長度的一個參數(shù)。意思是,如果單行的長度超過這個值,就會換一種算法
新的算法只會講排序的列(name字段)和主鍵id放入sort_buffer;
 所以排序的結果就少了city和age字段值,不能直接返回。
 執(zhí)行流程如下:
 1、初始化sort_buffer,確定放入name和id字段;
 2、從city索引中找到第一個滿足city = '杭州’條件的主鍵id,也就是圖中的ID_X;
 3、到主鍵id索引取出整行,取name、id兩個字段,存入sort_buffer;
 4、從city索引取下一條記錄的主鍵id
 5、重復step3、4直到不滿足city = '杭州’為止
 6、對sort_buffer中的數(shù)據按照字段name進行排序
 7、遍歷排序結果,取前1000行,并按照id的值回到原表中取出city、name、age三個字段返回給客戶端
rowid 方式和全字段方式一樣,需要先把查詢到的結果全部放在內存或硬盤中,再使用相關算法進行排序。而排序后由于沒有保存所需的字段,需要按順序使用主鍵再從索引樹上查詢,查到一個就返回一個,而不用把所有內容查完放到內存上再一并返回。
兩者比較
| 全字段排序 | rowid 排序 | 
如果擔心排序內存太小,會影響排序效率,才會采用rowid排序算法,這樣排序過程中依次可以排序更多行,但是需要再回到原表去取數(shù)據。
 如果MySQL認為內存足夠大,會優(yōu)先選擇全字段排序,把需要的字段都放到sort_buffer中,這樣排序后就會直接從內存里面返回查詢結果了,不用再回到原表中取數(shù)據。
對于InnoDB,rowid排序會要求回表多造成磁盤讀,因此不會被優(yōu)先選擇。
總結
以上是生活随笔為你收集整理的《MySQL——order by逻辑(全字段排序与rowid排序)》的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 《MySQL——count()逻辑》
 - 下一篇: 海南房价多少钱啊?