溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

mysql排序的有什么區(qū)別

發(fā)布時間:2020-09-16 11:35:32 來源:億速云 閱讀:124 作者:小新 欄目:MySQL數(shù)據(jù)庫

這篇文章將為大家詳細(xì)講解有關(guān)mysql排序的有什么區(qū)別,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

排序是數(shù)據(jù)庫中的一個基本功能,MySQL也不例外。

用戶通過Order by語句即能達(dá)到將指定的結(jié)果集排序的目的,其實不僅僅是Order by語句,Group by語句,Distinct語句都會隱含使用排序。本文首先會簡單介紹SQL如何利用索引避免排序代價,然后會介紹MySQL實現(xiàn)排序的內(nèi)部原理。

解決大家的以下疑問:

MySQL在哪些地方會使用排序,怎么判斷MySQL使用了排序;

MySQL有幾種排序模式,通過什么方法讓MySQL選擇不同的排序模式;

MySQL排序跟read_rnd_buffer_size有啥關(guān)系,在哪些情況下增加read_rnd_buffer_size能優(yōu)化排序;

怎么判斷MySQL使用到了磁盤來排序,怎么避免或者優(yōu)化磁盤排序;

排序時變長字段(varchar)數(shù)據(jù)在內(nèi)存是怎么存儲的,5.7有哪些改進;

在情況下,排序模式有哪些改進;

sort_merge_pass到底是什么 ,該狀態(tài)值過大說明了什么問題,可以通過什么方法解決;

MySQL使用到了排序的話,依次可以通過什么辦法分析和優(yōu)化讓排序更快?

二、排序

我們通過explain查看MySQL執(zhí)行計劃時,經(jīng)常會看到在Extra列中顯示Using filesort。

對于不能利用索引避免排序的SQL,數(shù)據(jù)庫不得不自己實現(xiàn)排序功能以滿足用戶需求,此時SQL的執(zhí)行計劃中會出現(xiàn)“Using filesort”,這里需要注意的是filesort并不意味著就是文件排序,其實也有可能是內(nèi)存排序,這個主要由sort_buffer_size參數(shù)與結(jié)果集大小確定。

其實這種情況就說明MySQL使用了排序。Using filesort經(jīng)常出現(xiàn)在order by、group by、distinct、join等情況下。

MySQL內(nèi)部實現(xiàn)排序主要有3種方式,常規(guī)排序,優(yōu)化排序和優(yōu)先隊列排序。

CREATE TABLE t1(id int, col1 varchar(64), col2 varchar(64), col3 varchar(64), PRIMARY KEY(id),key(col1,col2));
SELECT col1,col2,col3 FROM t1 WHERE col1>100 ORDER BY col2;

請看這三種排序的區(qū)別:

a.常規(guī)排序

(1).從表t1中獲取滿足WHERE條件的記錄

(2).對于每條記錄,將記錄的主鍵+排序鍵(id,col2)取出放入sort buffer

(3).如果sort buffer可以存放所有滿足條件的(id,col2)對,則進行排序;否則sort buffer滿后,進行排序并固化到臨時文件中。(排序算法采用的是快速排序算法)

(4).若排序中產(chǎn)生了臨時文件,需要利用歸并排序算法,保證臨時文件中記錄是有序的

(5).循環(huán)執(zhí)行上述過程,直到所有滿足條件的記錄全部參與排序

(6).掃描排好序的(id,col2)對,并利用id去撈取SELECT需要返回的列(col1,col2,col3)

(7).將獲取的結(jié)果集返回給用戶。

從上述流程來看,是否使用文件排序主要看sort buffer是否能容下需要排序的(id,col2)對,這個buffer的大小由sort_buffer_size參數(shù)控制。此外一次排序需要兩次IO,一次是撈(id,col2),第二次是撈(col1,col2,col3),由于返回的結(jié)果集是按col2排序,因此id是亂序的,通過亂序的id去撈(col1,col2,col3)時會產(chǎn)生大量的隨機IO。對于第二次MySQL本身一個優(yōu)化,即在撈之前首先將id排序,并放入緩沖區(qū),這個緩存區(qū)大小由參數(shù)read_rnd_buffer_size控制,然后有序去撈記錄,將隨機IO轉(zhuǎn)為順序IO。

b.優(yōu)化排序

常規(guī)排序方式除了排序本身,還需要額外兩次IO。優(yōu)化的排序方式相對于常規(guī)排序,減少了第二次IO。主要區(qū)別在于,放入sort buffer不是(id,col2),而是(col1,col2,col3)。由于sort buffer中包含了查詢需要的所有字段,因此排序完成后可以直接返回,無需二次撈數(shù)據(jù)。這種方式的代價在于,同樣大小的sort buffer,能存放的(col1,col2,col3)數(shù)目要小于(id,col2),如果sort buffer不夠大,可能導(dǎo)致需要寫臨時文件,造成額外的IO。當(dāng)然MySQL提供了參數(shù)max_length_for_sort_data,只有當(dāng)排序元組小于max_length_for_sort_data時,才能利用優(yōu)化排序方式,否則只能用常規(guī)排序方式。

c.優(yōu)先隊列排序

為了得到最終的排序結(jié)果,無論怎樣,我們都需要將所有滿足條件的記錄進行排序才能返回。那么相對于優(yōu)化排序方式,是否還有優(yōu)化空間呢?5.6版本針對Order by limit M,N語句,在空間層面做了優(yōu)化,加入了一種新的排序方式--優(yōu)先隊列,這種方式采用堆排序?qū)崿F(xiàn)。堆排序算法特征正好可以解limit M,N 這類排序的問題,雖然仍然需要所有元素參與排序,但是只需要M+N個元組的sort buffer空間即可,對于M,N很小的場景,基本不會因為sort buffer不夠而導(dǎo)致需要臨時文件進行歸并排序的問題。對于升序,采用大頂堆,最終堆中的元素組成了最小的N個元素,對于降序,采用小頂堆,最終堆中的元素組成了最大的N的元素。

關(guān)于mysql排序的有什么區(qū)別就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI