mysql orderby多个_MySQL OrderBy
MySQL會為每個線程分配一個內(nèi)存(sort_buffer)用于排序,該內(nèi)存小大為 sort_buffer_size
如果排序的數(shù)量小于 sort_buffer_size,排序?qū)趦?nèi)存中完成。
如果排序數(shù)據(jù)量很大,內(nèi)存中無法存下這么多數(shù)據(jù),則會使用磁盤臨時文件來輔助排序,也稱外部排序
在使用外部排序時,MySQL 會分成好幾份單獨(dú)的臨時文件用來存放排序后的數(shù)據(jù),然后再將這些文件合并成一個大文件
MySQL 會通過遍歷索引將滿足條件的數(shù)據(jù)讀到 sort_buffer,并且按照排序字段進(jìn)行快速排序
如果查詢的字段不包含在輔助索引中,需要按照輔助索引記錄的主鍵返回聚集索引所需字段。
該方式會造成隨機(jī) IO,在MySQL 5.6提供了 MRR 機(jī)制,會將副主索引匹配記錄的主鍵取出來再內(nèi)存中進(jìn)行排序,然后再回表
按照情況建立聯(lián)合索引來避免排序鎖帶來的性能損耗,允許的情況下也可以建立覆蓋索引來避免回表。
全字段排序
通過索引將所需的字段全部讀取到 sort_buffer 中
按照排序字段進(jìn)行排序
將結(jié)果返回給客戶端
缺點(diǎn):
造成sort_buffer 中存放不下很多數(shù)據(jù),因?yàn)槌伺判蜃侄芜€存放其他字段,對 sort_buffer 的利用效率不高
當(dāng)所需排序數(shù)據(jù)量很大時,會有很多的臨時文件,排序性能也會很差
優(yōu)點(diǎn): MySQL 認(rèn)為內(nèi)存足夠大時會優(yōu)先選擇全字段排序,因?yàn)檫@種方式比 row_id排序避免了一次回表操作
rowid 排序
通過控制排序的行數(shù)據(jù)的長度來讓 sort_buffer 中盡可能多地存放數(shù)據(jù),max_length_for_sort_data
只將需要排序的字段和主鍵讀到 sort_buffer 中,并按照排序字段進(jìn)行排序
按照排序后的順序,取id 進(jìn)行回表取出想要獲取的數(shù)據(jù)
將結(jié)果集返回給客戶端
優(yōu)點(diǎn):更好地利用內(nèi)存的 sort_buffer 進(jìn)行排序操作,盡量減少對磁盤的訪問
缺點(diǎn):回表的操作時隨機(jī) IO,會造成大量的隨機(jī)讀,不一定就比全字段排序減少對磁盤的訪問
按照排序的結(jié)果返回客戶端所取行數(shù)
隨機(jī)取出三行數(shù)據(jù)的需求
order by rand() 這個語句需要 Using temporary 和 Using filesort,查詢的執(zhí)行代價(jià)比較大
使用表的主鍵 id 的最大值和最小值來做隨機(jī)算法。
這種方法如果在 id 有空洞的情況下,就不是真正的隨機(jī)。代價(jià)比 1 小很多,因?yàn)橹皇褂昧?id 字段,沒有像1 一樣,需要在 order by rand() 方法組成的臨時表排序,再獲取 rowid 再回表。如果數(shù)據(jù)庫使用了軟刪除,就可以避免空洞的情況,減少掃描行數(shù)。
取出整個表的行數(shù)C,隨機(jī)獲取三個隨機(jī)值y1,y2,y3,limit y,1 得到三個數(shù)據(jù)。掃描行數(shù) 是 總行數(shù)c+(y1+1)+(y2+1)+(y3+1)
可以進(jìn)一步優(yōu)化:limit Ymin, (Ymax-Ymin), 取出id 后計(jì)算出 Y1,Y2,Y3對應(yīng)的 id ,然后 select in ids,掃描行數(shù)減少為 C + ymax +3.
在實(shí)際的應(yīng)用中,應(yīng)該避免讓 mysql 來排序,盡量將業(yè)務(wù)邏輯寫在業(yè)務(wù)代碼中,讓數(shù)據(jù)庫只做 “讀寫數(shù)據(jù)” 的事情。
總結(jié)
以上是生活随笔為你收集整理的mysql orderby多个_MySQL OrderBy的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java录入会员信息_java-第三章-
- 下一篇: mysql-bin.index找不到_M