MySql 你知道 order by 是怎么回事嗎? MySql全字段排序與 rowid 排序
1 前言
如下我這里有一張抽題記錄表,部分建表語(yǔ)句如下:
目前我在這個(gè)表中保存了 4000 萬(wàn)左右的數(shù)句,如下我執(zhí)行查詢語(yǔ)句:
你知道這個(gè)過(guò)程 order by 是怎么操作的嗎?

2 MySql 全字段排序
在這個(gè) question_extracting 抽題表中 ,我們?yōu)?user_id 添加了普通索引,所在在執(zhí)行上述這個(gè)查詢時(shí),會(huì)走索引查詢,
在上述這個(gè)查詢,MySql 需要對(duì)查詢結(jié)果進(jìn)行排序,MySQL 會(huì)給每個(gè)線程分配一 塊內(nèi)存用于排序,稱為 sort_buffer。
對(duì)于上述這個(gè)查詢,它的查詢過(guò)程如下:
第一步 初始化 sort_buffer 區(qū)域 ,確定放入 total_score、question_number 、create_time 字段
第二步 從索引 user_id 中 找到第一個(gè)滿足 user_id='760’ 條件的主鍵 id
第三步 回表到主鍵 id 索引取出整行,取 total_score、question_number 、create_time 三個(gè)字段的值,存入 sort_buffer 中
第四步 從索引 user_id 取下一個(gè)記錄的主鍵 id
然后重復(fù) 第三步 和 第四步 直到 user_id 的值不滿足查詢條件為止
查詢結(jié)束后,對(duì) sort_buffer 中的數(shù)據(jù)按照字段 total_score 做快速排序
最后 按照排序結(jié)果取前 1000 行返回給客戶端

在上述的這個(gè)排序過(guò)程,我們可以稱為 全字段排序 。
參數(shù) sort_buffer_size ,MySQL 為排序開(kāi)辟的內(nèi)存(sort_buffer)的大小,如果將要排序的數(shù)據(jù)量小于 sort_buffer_size,排序就在內(nèi)存中完成;如果排序數(shù)據(jù)量太大,內(nèi)存放不下,就需要使用用磁盤臨時(shí)文件輔助排序,可稱為 外部排序 。
在外部排序中,MySQL 將需要排序的數(shù)據(jù)分成 N 份,使用參數(shù) number_of_tmp_files 來(lái)表示,每一份單獨(dú)排序后存在這些臨時(shí)文件中,然后把這 N 個(gè)有序文件再合并成一個(gè)有序的大文件。
在內(nèi)存排序中,number_of_tmp_files的值為0,在外部排序中,number_of_tmp_files的值大于0,sort_buffer_size 的值越小,需要排序的數(shù)據(jù)量就需要分成的份數(shù)越多,number_of_tmp_files的值就越大。
3 MySql rowid 排序
MySql rowid 排序應(yīng)用于 當(dāng)查詢要返回的字段很多的時(shí)候,這種情況下,使用全字段排序,如果單行很大,排序的數(shù)據(jù)量也會(huì)很大,排序的性能會(huì)很差。
參數(shù) max_length_for_sort_data,在 MySQL 中控制用于排序的行數(shù)據(jù)的長(zhǎng)度,如果單行的長(zhǎng)度超過(guò)這個(gè)值,MySQL的排序算法就會(huì)將全字段排序切換為 rowid 排序。
如在這個(gè)查詢中,在rowid 排序中,只有要排序的列 total_score 和主鍵 id 會(huì)放入到 sort_buffer 中,它的查詢過(guò)程如下:
第一步 初始化 sort_buffer 區(qū)域 ,確定放入兩個(gè)字段 total_score、id字段
第二步 從索引 user_id 中 找到第一個(gè)滿足 user_id='760’ 條件的主鍵 id
第三步 回表到主鍵 id 索引取出整行,取 total_score、id兩個(gè)字段的值,存入 sort_buffer 中
第四步 從索引 user_id 取下一個(gè)記錄的主鍵 id
然后重復(fù) 第三步 和 第四步 直到 user_id 的值不滿足查詢條件為止
查詢結(jié)束后,對(duì) sort_buffer 中的數(shù)據(jù)按照字段 total_score 做快速排序
然后從 sort_buffer 中取出 排序好的 id ,依次回表查詢獲取前 1000行

對(duì)比全字段排序與 rowid 排序,rowid 排序要比 全字段排序多一次回表查詢操作,所以 對(duì)于 InnoDB 表來(lái)說(shuō),rowid 排序會(huì)要求回表多造成磁盤讀,因此不會(huì)被優(yōu)先選擇。
4 explain 命令
用 explain 命令來(lái)查看上述查詢語(yǔ)句的執(zhí)行情況

Extra 這個(gè)字段中的“Using filesort”表示的就是需要排序。
完畢
不局限于思維,不局限語(yǔ)言限制,才是編程的最高境界。