国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|數據庫技術|

服務器之家 - 數據庫 - Mysql - MySQL ORDER BY 的實現分析

MySQL ORDER BY 的實現分析

2019-12-06 15:48MYSQL教程網 Mysql

總的來說,在 MySQL 中的ORDER BY有兩種排序實現方式,一種是利用有序索引獲取有序數據,另一種則是通過相應的排序算法,將取得的數據在內存中進行排序

下面將通過實例分析兩種排序實現方式及實現圖解:
假設有 Table A 和 B 兩個表結構分別如下:
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、利用有序索引進行排序,實際上就是當我們 Query 的 ORDER BY 條件和 Query 的執行計劃中所利用的 Index 的索引鍵(或前面幾個索引鍵)完全一致,且索引訪問方式為 rang、 ref 或者 index 的時候,MySQL 可以利用索引順序而直接取得已經排好序的數據。這種方式的 ORDER BY 基本上可以說是最優的排序方式了,因為 MySQL 不需要進行實際的排序操作。

假設我們在Table A 和 B 上執行如下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

我們通過執行計劃可以看出,MySQL實際上并沒有進行實際的排序操作,實際上其整個執行過程如下圖所示:

MySQL ORDER BY 的實現分析

2、通過相應的排序算法,將取得的數據在內存中進行排序方式,MySQL 比需要將數據在內存中進行排序,所使用的內存區域也就是我們通過 sort_buffer_size 系統變量所設置的排序區。這個排序區是每個 Thread 獨享的,所以說可能在同一時刻在 MySQL 中可能存在多個 sort buffer 內存區域。

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

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

我們再看看 MySQL 需要使用 filesort 實現排序的實例。

假設我們改變一下我們的 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 中取出了符合條件的數據,由于取得的數據并不滿足 ORDER BY 條件,所以 MySQL 進行了 filesort 操作,其整個執行過程如下圖所示:

MySQL ORDER BY 的實現分析

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

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

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

實際執行過程應該是如下圖所示:
MySQL ORDER BY 的實現分析

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 欧美99| 日韩在线视频一区 | 日韩精品一区二区在线 | 国产婷婷精品 | 在线91av | 日韩精品在线播放 | 欧美色综合天天久久综合精品 | 成人免费视频网站在线看 | 日韩一区二区三区视频 | 亚洲午夜成激人情在线影院 | 免费一区 | 亚洲自拍偷拍精品 | 国产精品国产自产拍高清av | 毛片在线观看网站 | 日韩精品一 | 国产精品久久久久aaaa | 欧美一区二区三区久久 | 久久伊人成人网 | 日韩中文字幕在线播放 | 国产午夜精品一区二区三区 | 亚洲视频二区 | 国产精品123区 | 亚洲精品国产综合99久久夜夜嗨 | 久久激情五月丁香伊人 | 中文字幕日韩在线视频 | 午夜精品久久久久久久久久久久 | 欧美日韩一级在线观看 | 亚洲一区 | 国产一区二区三区视频 | 日韩成人中文字幕 | 欧美人成在线视频 | 国产黄网站 | 国产精品自在线 | 精品成人一区二区 | 日韩精品在线观看视频 | 成人资源在线观看 | 欧美成人精品一区 | 欧美精品一区三区 | 亚洲国产一区二区三区 | 久久久久久婷婷 | 日韩欧美一区二区三区在线观看 |