成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

聊聊 Order By 是怎么實(shí)現(xiàn)的?

數(shù)據(jù)庫(kù) Oracle
實(shí)際上,row_id 是 MySQL 的一種優(yōu)化算法,它首先考慮使用全字段排序。只有在認(rèn)為字段長(zhǎng)度過(guò)長(zhǎng)可能影響效率時(shí),才會(huì)采用 row_id 排序方式。此外,如果能夠利用 sort_buffer 完成排序,MySQL 就不會(huì)使用臨時(shí)文件。

首先排序功能由 ORDER BY 實(shí)現(xiàn),具體排列順序取決于優(yōu)化器的選擇。若優(yōu)化器認(rèn)為索引排序更有效率,則使用索引排序;反之,則使用 filesort(執(zhí)行計(jì)劃中額外信息提示:使用 filesort)。然而,索引排序的適用情況有限,且不確定性較高,通常還是會(huì)采用 filesort。

在 filesort 排序中,如果排序的數(shù)據(jù)較少,可在內(nèi)存中的 sort_buffer 上完成;否則,需借助臨時(shí)文件進(jìn)行排序。實(shí)際排序過(guò)程中,如果字段長(zhǎng)度較短,可直接在 sort_buffer 中進(jìn)行全字段排序并返回結(jié)果集。若字段長(zhǎng)度較長(zhǎng),可能出于空間考量,采用基于 row_id 的排序,此時(shí)會(huì)進(jìn)行二次回表后返回結(jié)果集。

索引排序

眾所周知,索引具備天然的排序?qū)傩裕虼嗽谑褂?ORDER BY 時(shí),若能充分利用索引,則效率必然最佳。

MySQL 確實(shí)可以基于索引執(zhí)行 ORDER BY 查詢,然而這一過(guò)程是否必然使用索引完全由優(yōu)化器決定。

CREATE TABLE `t2` (
  `id` INT(11),
  `a` varchar(64) NOT NULL,
  `b` varchar(64) NOT NULL,
  `c` varchar(64) NOT NULL,
  `d` varchar(64) NOT NULL,
  `f` varchar(64) DEFAULT NULL,
  PRIMARY KEY(id),
  UNIQUE KEY `f` (`f`),
  KEY `idx_abc` (`a`,`b`,`c`)
  KEY `idx_a` (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

假設(shè)存在如上所述的表格,在排序過(guò)程中可能會(huì)出現(xiàn)以下情況(由于優(yōu)化器的干預(yù),以下結(jié)果并不一定可以 100%復(fù)現(xiàn)。根據(jù)我的實(shí)驗(yàn),在 MySQL 5.7 環(huán)境中是可以的)。

select * from t2 order by a;

-- 不走索引,使用filesort(后面介紹啥是filesort)


select * from t2 order by a limit 100;

-- 走索引


select a,b from t2 order by a limit 100;

-- 走索引


select a,b,c from t2 order by a;

-- 走索引


select a,b,c,d from t2 order by a;

-- 不走索引,使用filesort


select a,b,c,d from t2 where a = "Paidaxing" order by b;

-- 走索引


select a,b,c,d from t2 where b = "Paidaxing" order by a;

-- 不走索引,使用filesort

在使用索引字段進(jìn)行排序時(shí),優(yōu)化器會(huì)根據(jù)成本評(píng)估來(lái)選擇是否通過(guò)索引進(jìn)行排序。經(jīng)過(guò)我的多次驗(yàn)證,以下情況中,索引排序的概率較高:

  • 查詢的字段和 ORDER BY 的字段組成了一個(gè)聯(lián)合索引,并且查詢條件符合最左前綴匹配,使得查詢可以使用索引覆蓋。例如:SELECT a, b, c FROM t2 ORDER BY a;
  • 查詢條件中包含了 LIMIT,并且 LIMIT 的數(shù)量不是很大。(在我測(cè)試的表中,數(shù)據(jù)量為 80 萬(wàn),當(dāng) LIMIT 超過(guò) 2 萬(wàn)多時(shí)就不再使用索引排序),例如:ORDER BY a LIMIT 100
  • 雖然未遵循最左前綴匹配,但是前導(dǎo)列通過(guò)常量進(jìn)行了查詢,例如:WHERE a = "Paidaxing" ORDER BY b

filesort 排序

如果無(wú)法使用或優(yōu)化器認(rèn)為索引排序效率不高,MySQL 將執(zhí)行 filesort 操作,以讀取表中的行并對(duì)它們進(jìn)行排序。

在排序過(guò)程中,MySQL 為每個(gè)線程分配一塊內(nèi)存用于排序,稱為sort_buffer,其大小由 sort_buffer_size控制。

根據(jù) sort_buffer_size 的大小不同,排序操作會(huì)發(fā)生在不同的位置:

  • 如果排序數(shù)據(jù)量小于 sort_buffer_size,則排序在內(nèi)存中完成。
  • 如果排序數(shù)據(jù)量大于 sort_buffer_size,則需要利用磁盤臨時(shí)文件輔助排序。

臨時(shí)文件排序采用歸并排序算法,首先將需要排序的數(shù)據(jù)分配到多個(gè)臨時(shí)文件中,同時(shí)進(jìn)行排序操作,然后將多個(gè)排序完成的文件合并成一個(gè)結(jié)果集返回給客戶端。相對(duì)于在內(nèi)存中的 sort_buffer 排序,磁盤上的臨時(shí)文件排序速度較慢。

除了sort_buffer_size參數(shù)之外,影響排序算法的另一個(gè)關(guān)鍵參數(shù)是 max_length_for_sort_data。

max_length_for_sort_data 是 MySQL 中控制用于排序的行數(shù)據(jù)的長(zhǎng)度的一個(gè)參數(shù),默認(rèn)值為 1024 字節(jié)。如果單行長(zhǎng)度超過(guò)該值,MySQL 就會(huì)認(rèn)為單行太大,因此會(huì)采用 rowid 排序;否則,會(huì)進(jìn)行全字段排序。

全字段排序

所謂全字段排序,即將要查詢的所有字段都放入 sort_buffer 中,然后根據(jù)排序字段進(jìn)行排序,排序完成后直接將結(jié)果集返回給客戶端。

假設(shè)我們有以下查詢 SQL:

select a,d,f from t2 where a = "Paidaxing" order by d;

--

因?yàn)榇颂幧婕暗淖侄螢?a、d、f 三個(gè),因此將滿足 WHERE 條件的所有數(shù)據(jù)的 a、d、f 字段都放入 sort_buffer 中,然后根據(jù) d 字段在 sort_buffer 中進(jìn)行排序,排序完成后返回給客戶端的大致過(guò)程如下:

  1. 從索引 a 中取出滿足條件 a = "Paidaxing" 的第一條記錄的主鍵 ID。
  2. 根據(jù)主鍵 ID 回表,提取 a、d、f 三個(gè)字段的值,并將它們存入 sort_buffer。
  3. 繼續(xù)查詢下一個(gè)符合 a = "Paidaxing" 條件的記錄,重復(fù)執(zhí)行第 1 和第 2 步驟。
  4. 在 sort_buffer 中根據(jù) d 字段進(jìn)行排序。
  5. 將排序后的結(jié)果集返回給客戶端。

圖片圖片

以上過(guò)程中,如果數(shù)據(jù)在 sort_buffer 中無(wú)法全部存放,則會(huì)使用臨時(shí)文件,并對(duì)臨時(shí)文件進(jìn)行歸并排序。

全字段排序的優(yōu)點(diǎn)在于只需要對(duì)原表進(jìn)行一次回表查詢(每條記錄只需回表一次),排序完成后可以直接返回所需字段,因此效率較高。但其缺點(diǎn)在于,如果要查詢的字段較多,會(huì)占用大量 sort_buffer 空間,導(dǎo)致可存儲(chǔ)的數(shù)據(jù)量減少。當(dāng)需要排序的數(shù)據(jù)量增大時(shí),可能會(huì)使用臨時(shí)文件,從而導(dǎo)致整體性能下降。

為避免這個(gè)問(wèn)題,可以采用 row_id 排序的方式。

row_id 排序

這個(gè)也很好理解,即在構(gòu)建 sort_buffer 時(shí),不需要將所有要查詢的字段都放進(jìn)去,只需要將排序字段和主鍵放入即可。

select a,d,f from t2 where a = "Paidaxing" order by d;

比如這個(gè) SQL,只需要將 d 和 id 放入 sort_buffer 中,首先按照 d 進(jìn)行排序。排序完成后,根據(jù) id 將對(duì)應(yīng)的 a、d、f 幾個(gè)字段查詢出來(lái),然后返回給客戶端的大致過(guò)程如下:

  1. 從索引 a 中取出符合條件 a = "Paidaxing" 的第一條記錄的主鍵 ID。
  2. 根據(jù)主鍵 ID 回表,提取 d 字段的值,并將其存入 sort_buffer。
  3. 繼續(xù)查詢下一個(gè)符合條件 a = "Paidaxing" 的記錄,重復(fù)執(zhí)行第 1 和第 2 步驟。
  4. 在 sort_buffer 中根據(jù) d 進(jìn)行排序。
  5. 根據(jù)排序后的 id,回表查詢出對(duì)應(yīng)的 a、d、f 幾個(gè)字段。
  6. 將結(jié)果集返回給客戶端。

圖片圖片

以上的第五步,與全字段排序算法相比確實(shí)多了一次回表操作。因此,這種方案的效率肯定會(huì)稍慢一些。

如何選擇

如何選擇排序方式?

實(shí)際上,row_id 是 MySQL 的一種優(yōu)化算法,它首先考慮使用全字段排序。只有在認(rèn)為字段長(zhǎng)度過(guò)長(zhǎng)可能影響效率時(shí),才會(huì)采用 row_id 排序方式。此外,如果能夠利用 sort_buffer 完成排序,MySQL 就不會(huì)使用臨時(shí)文件。

綜上所述,MySQL 在選擇排序方式時(shí)會(huì)優(yōu)先考慮速度、內(nèi)存和減少回表次數(shù)等因素。

責(zé)任編輯:武曉燕 來(lái)源: 碼上遇見你
相關(guān)推薦

2021-09-22 05:55:18

Eslint disble算法

2021-07-02 07:06:20

調(diào)試代碼crash

2022-06-09 09:20:41

ahooksaxios

2022-09-30 00:03:03

JS斷點(diǎn)線程

2022-10-08 00:07:00

JSV8調(diào)用棧

2024-12-23 15:05:29

2021-08-23 08:27:43

innodb數(shù)據(jù)庫(kù)存儲(chǔ)引擎

2022-02-11 09:31:23

IPV4IP地址IANA

2022-02-18 08:26:12

TopK數(shù)組面試題

2021-07-14 14:05:24

Fragment項(xiàng)目結(jié)構(gòu)

2020-06-17 07:40:26

監(jiān)控系統(tǒng)zabbix

2021-07-26 05:10:13

JavaJakarta EEJSR

2021-07-20 08:03:43

微服務(wù)應(yīng)用程序

2022-05-30 16:19:26

C#多態(tài)底層虛方法

2021-02-05 08:42:21

云原生系統(tǒng)方式

2022-03-18 10:43:12

WebSocketHTML5TCP 連接

2017-03-06 16:51:52

Java泛型實(shí)現(xiàn)

2023-01-26 00:59:39

B-Treegolang度量衡

2022-08-05 08:27:05

分布式系統(tǒng)線程并發(fā)

2025-04-24 00:00:00

Spring AI流式輸出AI 模型
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 亚洲高清av | 免费观看一级视频 | 国家一级黄色片 | 99热在这里只有精品 | 午夜欧美 | 国内精品久久精品 | 成人深夜小视频 | 一区二区精品 | 91久久精品视频 | av性色| 香蕉婷婷| 国产在线不卡视频 | 欧美精品一区二区在线观看 | 亚洲中午字幕 | av在线天堂网 | 国产精品精品久久久久久 | 日韩视频免费看 | 亚洲一区 中文字幕 | 亚洲精品18| 国产精品视频久久 | 美女黄色在线观看 | 久久不卡 | 日韩电影一区 | 在线免费观看a级片 | 色就是色欧美 | 欧美一区二区三区 | 黄色毛片网站在线观看 | 亚洲精品久久久一区二区三区 | 鲁大师一区影视 | 国产亚洲精品久久久久久牛牛 | 超碰男人天堂 | 一级做a爰片性色毛片 | 一区二区中文字幕 | 一级毛片视频 | 欧美lesbianxxxxhd视频社区 | 中文字幕精品一区二区三区精品 | 日韩av免费在线观看 | 亚洲国产成人精品久久久国产成人一区 | 国产激情第一页 | 国产精品明星裸体写真集 | 人人爽人人草 |