欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MySQL ORDER BY 的實(shí)現(xiàn)分析

 更新時(shí)間:2012年07月29日 23:46:54   作者:  
總的來說,在 MySQL 中的ORDER BY有兩種排序?qū)崿F(xiàn)方式,一種是利用有序索引獲取有序數(shù)據(jù),另一種則是通過相應(yīng)的排序算法,將取得的數(shù)據(jù)在內(nèi)存中進(jìn)行排序

下面將通過實(shí)例分析兩種排序?qū)崿F(xiàn)方式及實(shí)現(xiàn)圖解:
假設(shè)有 Table A 和 B 兩個(gè)表結(jié)構(gòu)分別如下:
sky@localhost : example 01:48:21> show create table AG
*************************** 1. row ***************************
Table: A
Create Table: CREATE TABLE `A` (
`c1` int(11) NOT NULL default ‘0′,
`c2` char(2) default NULL,
`c3` varchar(16) default NULL,
`c4` datetime default NULL,
PRIMARY KEY  (`c1`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

sky@localhost : example 01:48:32> show create table BG
*************************** 1. row ***************************
Table: B
Create Table: CREATE TABLE `B` (
`c1` int(11) NOT NULL default ‘0′,
`c2` char(2) default NULL,
`c3` varchar(16) default NULL,
PRIMARY KEY  (`c1`),
KEY `B_c2_ind` (`c2`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

1、利用有序索引進(jìn)行排序,實(shí)際上就是當(dāng)我們 Query 的 ORDER BY 條件和 Query 的執(zhí)行計(jì)劃中所利用的 Index 的索引鍵(或前面幾個(gè)索引鍵)完全一致,且索引訪問方式為 rang、 ref 或者 index 的時(shí)候,MySQL 可以利用索引順序而直接取得已經(jīng)排好序的數(shù)據(jù)。這種方式的 ORDER BY 基本上可以說是最優(yōu)的排序方式了,因?yàn)?MySQL 不需要進(jìn)行實(shí)際的排序操作。

假設(shè)我們?cè)赥able A 和 B 上執(zhí)行如下SQL:
sky@localhost : example 01:44:28> EXPLAIN SELECT A.* FROM A,B
-> WHERE A.c1 > 2 AND A.c2 < 5 AND A.c2 = B.c2 ORDER BY A.c1G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: A
type: range
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: NULL
rows: 3
Extra: Using where
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: B
type: ref
possible_keys: B_c2_ind
key: B_c2_ind
key_len: 7
ref: example.A.c2
rows: 2
Extra: Using where; Using index

我們通過執(zhí)行計(jì)劃可以看出,MySQL實(shí)際上并沒有進(jìn)行實(shí)際的排序操作,實(shí)際上其整個(gè)執(zhí)行過程如下圖所示:

2、通過相應(yīng)的排序算法,將取得的數(shù)據(jù)在內(nèi)存中進(jìn)行排序方式,MySQL 比需要將數(shù)據(jù)在內(nèi)存中進(jìn)行排序,所使用的內(nèi)存區(qū)域也就是我們通過 sort_buffer_size 系統(tǒng)變量所設(shè)置的排序區(qū)。這個(gè)排序區(qū)是每個(gè) Thread 獨(dú)享的,所以說可能在同一時(shí)刻在 MySQL 中可能存在多個(gè) sort buffer 內(nèi)存區(qū)域。

第二種方式在 MySQL Query Optimizer 所給出的執(zhí)行計(jì)劃(通過 EXPLAIN 命令查看)中被稱為 filesort。在這種方式中,主要是由于沒有可以利用的有序索引取得有序的數(shù)據(jù),MySQL只能通過將取得的數(shù)據(jù)在內(nèi)存中進(jìn)行排序然后再將數(shù)據(jù)返回給客戶端。在 MySQL 中 filesort 的實(shí)現(xiàn)算法實(shí)際上是有兩種的,一種是首先根據(jù)相應(yīng)的條件取出相應(yīng)的排序字段和可以直接定位行數(shù)據(jù)的行指針信息,然后在 sort buffer 中進(jìn)行排序。另外一種是一次性取出滿足條件行的所有字段,然后在 sort buffer 中進(jìn)行排序。

在 MySQL4.1 版本之前只有第一種排序算法,第二種算法是從 MySQL4.1開始的改進(jìn)算法,主要目的是為了減少第一次算法中需要兩次訪問表數(shù)據(jù)的 IO 操作,將兩次變成了一次,但相應(yīng)也會(huì)耗用更多的 sort buffer 空間。當(dāng)然,MySQL4.1開始的以后所有版本同時(shí)也支持第一種算法,MySQL 主要通過比較我們所設(shè)定的系統(tǒng)參數(shù) max_length_for_sort_data 的大小和 Query 語句所取出的字段類型大小總和來判定需要使用哪一種排序算法。如果 max_length_for_sort_data 更大,則使用第二種優(yōu)化后的算法,反之使用第一種算法。所以如果希望 ORDER BY 操作的效率盡可能的高,一定要主義 max_length_for_sort_data 參數(shù)的設(shè)置。曾經(jīng)就有同事的數(shù)據(jù)庫出現(xiàn)大量的排序等待,造成系統(tǒng)負(fù)載很高,而且響應(yīng)時(shí)間變得很長(zhǎng),最后查出正是因?yàn)?MySQL 使用了傳統(tǒng)的第一種排序算法而導(dǎo)致,在加大了 max_length_for_sort_data 參數(shù)值之后,系統(tǒng)負(fù)載馬上得到了大的緩解,響應(yīng)也快了很多。

我們?cè)倏纯?MySQL 需要使用 filesort 實(shí)現(xiàn)排序的實(shí)例。

假設(shè)我們改變一下我們的 Query,換成通過A.c2來排序,再看看情況:
sky@localhost : example 01:54:23> EXPLAIN SELECT A.* FROM A,B
-> WHERE A.c1 > 2 AND A.c2 < 5 AND A.c2 = B.c2 ORDER BY A.c2G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: A
type: range
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: NULL
rows: 3
Extra: Using where; Using filesort
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: B
type: ref
possible_keys: B_c2_ind
key: B_c2_ind
key_len: 7
ref: example.A.c2
rows: 2
Extra: Using where; Using index

MySQL 從 Table A 中取出了符合條件的數(shù)據(jù),由于取得的數(shù)據(jù)并不滿足 ORDER BY 條件,所以 MySQL 進(jìn)行了 filesort 操作,其整個(gè)執(zhí)行過程如下圖所示:

在 MySQL 中,filesort 操作還有一個(gè)比較奇怪的限制,那就是其數(shù)據(jù)源必須是來源于一個(gè) Table,所以,如果我們的排序數(shù)據(jù)如果是兩個(gè)(或者更多個(gè)) Table 通過 Join所得出的,那么 MySQL 必須通過先創(chuàng)建一個(gè)臨時(shí)表(Temporary Table),然后再將此臨時(shí)表的數(shù)據(jù)進(jìn)行排序,如下例所示:

sky@localhost : example 02:46:15> explain select A.* from A,B
-> where A.c1 > 2 and A.c2 < 5 and A.c2 = B.c2 order by B.c3G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: A
type: range
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: NULL
rows: 3
Extra: Using where; Using temporary; Using filesort
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: B
type: ref
possible_keys: B_c2_ind
key: B_c2_ind
key_len: 7
ref: example.A.c2
rows: 2
Extra: Using where

這個(gè)執(zhí)行計(jì)劃的輸出還是有點(diǎn)奇怪的,不知道為什么,MySQL Query Optimizer 將 “Using temporary” 過程顯示在第一行對(duì) Table A 的操作中,難道只是為讓執(zhí)行計(jì)劃的輸出少一行?

實(shí)際執(zhí)行過程應(yīng)該是如下圖所示:

相關(guān)文章

  • mysql建庫時(shí)提示Specified key was too long max key length is 1000 bytes的問題的解決方法

    mysql建庫時(shí)提示Specified key was too long max key length is 1000

    本文將詳細(xì)提供mysql建庫時(shí)提示Specified key was too long max key length is 1000 bytes的問題的解決方法,有需求的朋友可以參考
    2012-11-11
  • mysql 5.7.17 安裝教程 附MySQL服務(wù)無法啟動(dòng)的解決方法

    mysql 5.7.17 安裝教程 附MySQL服務(wù)無法啟動(dòng)的解決方法

    這篇文章主要為大家詳細(xì)介紹了mysql 5.7.17安裝教程,并且為大家分享了MySQL服務(wù)無法啟動(dòng)的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • 關(guān)于mysql 8.0.13zip包安裝方法

    關(guān)于mysql 8.0.13zip包安裝方法

    這篇文章主要介紹了關(guān)于mysql 8.0.13zip包安裝方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下
    2018-11-11
  • Mysql升級(jí)到5.7后遇到的group by查詢問題解決

    Mysql升級(jí)到5.7后遇到的group by查詢問題解決

    這篇文章主要給大家介紹了關(guān)于Mysql升級(jí)到5.7后遇到的group by查詢問題的解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)同樣遇到這個(gè)問題的朋友們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-09-09
  • MySQL日志設(shè)置及查看方法

    MySQL日志設(shè)置及查看方法

    這篇文章主要介紹了MySQL日志設(shè)置及查看方法,需要的朋友可以參考下
    2017-05-05
  • mysql學(xué)習(xí)筆記之基礎(chǔ)知識(shí)

    mysql學(xué)習(xí)筆記之基礎(chǔ)知識(shí)

    本文是MySQL學(xué)習(xí)筆記系列文章的第一篇,給大家簡(jiǎn)單講解下MySQL的一些檢查操作命令,希望大家能夠喜歡
    2017-02-02
  • 一文解答為什么MySQL的count()方法這么慢

    一文解答為什么MySQL的count()方法這么慢

    這篇文章主要介紹了一文解答為什么MySQL的count()方法這么慢,mysql用count方法查全表數(shù)據(jù),在不同的存儲(chǔ)引擎里實(shí)現(xiàn)不同,myisam有專門字段記錄全表的行數(shù),直接讀這個(gè)字段就好了
    2022-07-07
  • mysql仿asp的數(shù)據(jù)庫操作類

    mysql仿asp的數(shù)據(jù)庫操作類

    使用說明: 該類完全按照ADO的習(xí)慣書寫的,用過ASP的人都覺得ASP連接數(shù)據(jù)庫比PHP好用(這是我的感覺), 但PHP得一個(gè)一個(gè)API地寫,挺累,該類做了完全的封裝 創(chuàng)建類的實(shí)例時(shí)可以指定一個(gè)數(shù)據(jù)庫表和選擇的數(shù)據(jù)庫,如:new MySQLDB("table","database");
    2008-04-04
  • 關(guān)于MySql鏈接url參數(shù)的設(shè)置

    關(guān)于MySql鏈接url參數(shù)的設(shè)置

    最近整理了一下網(wǎng)上關(guān)于MySql 鏈接url 參數(shù)的設(shè)置以及常用的幾個(gè)較為重要的參數(shù),大家若感興趣可以參考下
    2014-03-03
  • mysql Sort aborted: Out of sort memory, consider increasing server sort buffer size的解決方法

    mysql Sort aborted: Out of sort memory, consider increasing

    這篇文章主要介紹了mysql Sort aborted: Out of sort memory, consider increasing server sort buffer size的解決方法,需要的朋友可以參考下
    2016-05-05

最新評(píng)論