最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2012年07月29日 23:46:54   作者:  
總的來(lái)說,在 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 語(yǔ)句所取出的字段類型大小總和來(lái)判定需要使用哪一種排序算法。如果 max_length_for_sort_data 更大,則使用第二種優(yōu)化后的算法,反之使用第一種算法。所以如果希望 ORDER BY 操作的效率盡可能的高,一定要主義 max_length_for_sort_data 參數(shù)的設(shè)置。曾經(jīng)就有同事的數(shù)據(jù)庫(kù)出現(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來(lái)排序,再看看情況:
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ù)源必須是來(lái)源于一個(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的max_allowed_packet設(shè)定

    Mysql的max_allowed_packet設(shè)定

    今天小編就為大家分享一篇關(guān)于Mysql的max_allowed_packet設(shè)定,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-12-12
  • mysql 維護(hù)常用命令

    mysql 維護(hù)常用命令

    需要維護(hù)mysql數(shù)據(jù)庫(kù)的朋友可以參考下。
    2009-11-11
  • MySQL實(shí)現(xiàn)分詞搜索(FULLTEXT)的方法

    MySQL實(shí)現(xiàn)分詞搜索(FULLTEXT)的方法

    這篇文章主要介紹了MySQL實(shí)現(xiàn)分詞搜索(FULLTEXT)的方法,包括全文搜索的簡(jiǎn)單使用,建表添加FULLTEXT索引使用該技術(shù)非常簡(jiǎn)單,首先需要有一張表,我建立了一張圖書表并插入了兩條數(shù)據(jù),需要的朋友可以參考下
    2022-10-10
  • mysql8.0?my.ini?如何永久修改時(shí)區(qū)

    mysql8.0?my.ini?如何永久修改時(shí)區(qū)

    這篇文章主要介紹了mysql8.0?my.ini?如何永久修改時(shí)區(qū),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • mysql 中 replace into 與 insert into on duplicate key update 的用法和不同點(diǎn)實(shí)例分析

    mysql 中 replace into 與 insert into on duplicate key update 的

    這篇文章主要介紹了mysql 中 replace into 與 insert into on duplicate key update 的用法和不同點(diǎn),結(jié)合實(shí)例形式分析了replace into 與 insert into on duplicate key update的功能、基本用法與操作注意事項(xiàng),需要的朋友可以參考下
    2020-02-02
  • mysql5.7.19 安裝配置方法圖文教程(win10)

    mysql5.7.19 安裝配置方法圖文教程(win10)

    這篇文章主要為大家分享了win10下mysql 5.7.19 安裝配置方法圖文教程,感興趣的朋友可以參考一下
    2017-07-07
  • MySQL如何優(yōu)化查詢速度

    MySQL如何優(yōu)化查詢速度

    這篇文章主要介紹了MySQL如何優(yōu)化查詢速度,幫助大家提升自己的數(shù)據(jù)庫(kù)性能,感興趣的朋友可以了解下
    2020-08-08
  • mysql語(yǔ)句如何插入含單引號(hào)或反斜杠的值詳解

    mysql語(yǔ)句如何插入含單引號(hào)或反斜杠的值詳解

    這篇文章主要給大家介紹了關(guān)于mysql語(yǔ)句如何插入含單引號(hào)或反斜杠的值的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • MySQL主從復(fù)制基于binlog與GTID詳解

    MySQL主從復(fù)制基于binlog與GTID詳解

    本文介紹了基于binlog和GTID的MySQL主從復(fù)制搭建步驟,包括準(zhǔn)備環(huán)境、創(chuàng)建授權(quán)賬戶、配置主從庫(kù)等,通過主從復(fù)制,可以實(shí)現(xiàn)數(shù)據(jù)的高可用、負(fù)載均衡和災(zāi)難恢復(fù),首先,確保環(huán)境一致性,然后在數(shù)據(jù)庫(kù)中創(chuàng)建具有復(fù)制權(quán)限的賬戶
    2024-10-10
  • 淺談MySQL 有哪些死鎖場(chǎng)景

    淺談MySQL 有哪些死鎖場(chǎng)景

    本文主要介紹了淺談MySQL 有哪些死鎖場(chǎng)景,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08

最新評(píng)論

沐川县| 南丰县| 鄱阳县| 应城市| 民丰县| 诏安县| 唐河县| 上蔡县| 英吉沙县| 剑川县| 兴文县| 沅陵县| 康定县| 沅江市| 商城县| 启东市| 宿州市| 廊坊市| 剑阁县| 体育| 泽库县| 枝江市| 古交市| 安陆市| 贺兰县| 南安市| 平和县| 师宗县| 灵寿县| 杭锦旗| 友谊县| 房产| 英山县| 扎赉特旗| 乌什县| 娱乐| 响水县| 静乐县| 青浦区| 浦北县| 元江|