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

MySQL order by原理以及優化?這篇來給你逐步解析

數據庫 MySQL
偏向于業務的 (MySQL)DBA 或者業務的開發者來說,order by 排序是一個常見的業務功能,將結果根據指定的字段排序,滿足前端展示的需求。然而排序操作也是經常出現慢查詢排行榜的座上賓。本文將從原理和實際案例優化,order by 使用限制等幾個方面來逐步了解 order by 排序。

MySQL order by原理以及優化?這篇來給你逐步解析

一 簡介

偏向于業務的 (MySQL)DBA 或者業務的開發者來說,order by 排序是一個常見的業務功能,將結果根據指定的字段排序,滿足前端展示的需求。然而排序操作也是經常出現慢查詢排行榜的座上賓。本文將從原理和實際案例優化,order by 使用限制等幾個方面來逐步了解 order by 排序。

二 原理

在了解 order by 排序的原理之前,強烈安利兩篇關于排序算法的文章 《歸并排序的實現》 《經典排序算法》。MySQL 支持兩種排序算法,常規排序和優化,并且在 MySQL 5.6 版本中 針對 order by limit M,N 做了特別的優化,這里列為第三種。

2.1 常規排序

a 從表 t1 中獲取滿足 WHERE 條件的記錄

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

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

d 若排序中產生了臨時文件,需要利用歸并排序算法,保證臨時文件中記錄是有序的

e 循環執行上述過程,直到所有滿足條件的記錄全部參與排序

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

g 將獲取的結果集返回給用戶。

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

2.2 優化排序

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

2.3 優先隊列排序

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

三 優化

通過上面的原理分析,我們知道排序的本質是通過一定的算法 (耗費 cpu 運算, 內存, 臨時文件 IO) 將結果集變成有序的結果集。如何優化呢?答案是分兩個方面利用索引的有序性 (MySQL 的 B+ 樹索引是默認從小到大遞增排序) 減少排序, ***的方式是直接不排序。

  1. create table t1( 
  2.   id int not null primary key , 
  3.   key_part1 int(10) not null
  4.   key_part2 varchar(10) not null default ''
  5.   key_part3 
  6.   key idx_kp1_kp2(key_part1,key_part2,key_part4), 
  7.   key idx_kp3(id) 
  8. ) engine=innodb default charset=utf8 

 

以下種類的查詢是可以利用到索引 idx_kp1_kp2 的

  1. SELECT * FROM t1 ORDER BY key_part1,key_part2,... ; 
  2. SELECT * FROM t1 WHERE key_part1 = constant ORDER BY key_part2; 
  3. SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 DESC
  4. SELECT * FROM t1 WHERE key_part1 = 1 ORDER BY key_part1 DESC, key_part2 DESC
  5. SELECT * FROM t1 WHERE key_part1 > constant ORDER BY key_part1 ASC
  6. SELECT * FROM t1 WHERE key_part1 < constant ORDER BY key_part1 DESC
  7. SELECT * FROM t1 WHERE key_part1 = constant1 AND key_part2 > constant2 ORDER BY key_part2 

 

溫馨提示 ,各位看官要辯證的看待官方給的例子,自己多動手實踐。

無法利用到索引排序的情況,其實我覺得這是本文的重點,對于廣大開發同學而言,記住那種不能利用索引排序會更簡單些。

1. 最常見的情況 用來查找結果的索引 (key2) 和 排序的索引 (key1) 不一樣,where a=x and b=y order by id;

  1. SELECT * FROM t1 WHERE key2=constant ORDER BY key1; 

2. 排序字段在不同的索引中,無法使用索引排序

  1. SELECT * FROM t1 ORDER BY key1,key2; 

3. 排序字段順序與索引中列順序不一致,無法使用索引排序,比如索引是 key idx_kp1_kp2(key_part1,key_part2)

  1. SELECT * FROM t1 ORDER BY key_part2, key_part1; 

4. order by 中的升降序和索引中的默認升降不一致,無法使用索引排序

  1. SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 ASC

5. ey_part1 是范圍查詢,key_part2 無法使用索引排序

  1. SELECT * FROM t1 WHERE key_part1> constant ORDER BY key_part2; 

5 rder by 和 group by 字段列不一致

  1. SELECT * FROM t1 WHERE key_part1=constant ORDER BY key_part2 group by key_part4; 

6. 索引本身是無序存儲的,比如 hash 索引,不能利用索引的有序性。

7. order by 字段只被索引了前綴 ,key idx_col(col(10))

  1. select * from t1 order by col ; 

8. 對于還有 join 的關聯查詢,排序字段并非全部來自于***個表,使用 explain 查看執行計劃***個表 type 值不是 const 。

當無法避免排序操作時, 又該如何來優化呢?很顯然, 優先選擇 using index 的排序方式,在無法滿足利用索引排序的情況下,盡可能讓 MySQL 選擇使用第二種單路算法來進行排序。這樣可以減少大量的隨機 IO 操作, 很大幅度地提高排序的效率。

1. 加大 max_length_for_sort_data 參數的設置

在 MySQL 中, 決定使用老式排序算法還是改進版排序算法是通過參數 max_length_for_sort_data 來決定的。當所有返回字段的***長度小于這個參數值時, MySQL 就會選擇改進后的排序算法, 反之, 則選擇老式的算法。所以, 如果有充足的內存讓 MySQL 存放須要返回的非排序字段, 就可以加大這個參數的值來讓 MySQL 選擇使用改進版的排序算法。

2. 去掉不必要的返回字段

當內存不是很充裕時, 不能簡單地通過強行加大上面的參數來強迫 MySQL 去使用改進版的排序算法, 否則可能會造成 MySQL 不得不將數據分成很多段, 然后進行排序, 這樣可能會得不償失。此時就須要去掉不必要的返回字段, 讓返回結果長度適應 max_length_for_sort_data 參數的限制。

同時也要規范 MySQL 開發規范,盡量避免大字段。當有 select 查詢列含有大字段 blob 或者 text 的時候, MySQL 會選擇常規排序。

" algorithm to use. It normally uses the modified algorithm except when or columns are involved, in which case it uses the original algorithm."

3. 增大 sort_buffer_size 參數設置

這個值如果過小的話, 再加上你一次返回的條數過多, 那么很可能就會分很多次進行排序, 然后***將每次的排序結果再串聯起來, 這樣就會更慢, 增大 sort_buffer_size 并不是為了讓 MySQL 選擇改進版的排序算法, 而是為了讓 MySQL 盡量減少在排序過程中對須要排序的數據進行分段, 因為分段會造成 MySQL 不得不使用臨時表來進行交換排序。但是這個值不是越大越好:

1. sort_buffer_size 是一個 connection 級參數, 在每個 connection ***次需要使用這個 buffer 的時候, 一次性分配設置的內存。

2. sort_buffer_size 并不是越大越好, 由于是 connection 級的參數, 過大的設置 + 高并發可能會耗盡系統內存資源。

3. 據說 sort_buffer_size 超過 2M 的時候, 就會使用 mmap() 而不是 malloc() 來進行內存分配, 導致效率降低。

四 參考文章

[1] MySQL order by 調優官方文檔

[2] MySQL 排序原理與案例分析

[3] 淘寶 MySQL 月報 

責任編輯:龐桂玉 來源: ITPUB
相關推薦

2020-10-19 19:45:58

MySQL數據庫優化

2021-03-10 08:47:46

反射Java對象

2009-03-26 13:43:59

實現Order ByMySQL

2023-02-27 10:17:05

EventBus觀察者模式

2018-01-19 14:39:53

瀏覽器頁面優化

2018-08-07 16:17:35

JavaMySQL數據庫

2019-10-10 11:20:22

MySQL索引數據庫

2015-04-30 14:05:18

Visual Stud

2025-04-02 07:29:14

2019-12-18 08:00:09

MySQL數據庫ORDER BY

2023-09-22 07:52:16

HDMI 2.14K HDR游戲

2020-01-13 10:45:35

JavaScript解析前端

2017-06-23 21:32:16

MySQL大數據優化

2017-09-18 09:26:51

PHP代碼大整數

2020-07-24 20:57:33

MySQL數據量數據庫

2022-02-21 22:58:25

排序rowid 排序優化

2010-11-25 10:28:28

MySQL查詢優化器

2025-01-15 12:48:30

2024-10-12 15:35:08

SQL索引數據庫

2023-08-07 08:20:27

圖解算法工具
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美日日 | 日本欧美在线观看视频 | 9久久精品| 欧美一级www片免费观看 | 久久毛片| 久久精品—区二区三区 | 欧美色欧美亚洲另类七区 | 国产在线小视频 | 一级免费看 | 久久com | 日韩国产欧美视频 | 毛片免费看的 | 成人在线播放网址 | 欧美v日韩v| 国产成人jvid在线播放 | 91中文在线观看 | 北条麻妃99精品青青久久 | 人人人干 | 日本一区二区三区精品视频 | 亚洲成人一区 | 久草视频观看 | 亚洲精品9999久久久久 | 日本亚洲一区 | 欧美五月婷婷 | 超碰97免费 | 欧美福利精品 | 成年人精品视频在线观看 | www国产成人免费观看视频,深夜成人网 | 亚洲色图综合 | 国产九九精品 | 午夜色婷婷 | 精品一区二区在线看 | 国产精品久久久久久婷婷天堂 | 成人在线小视频 | 免费精品视频在线观看 | 国产午夜精品一区二区三区嫩草 | 春色av| 欧美6一10sex性hd | 欧美国产日本一区 | 日日噜| 一区二区三区四区在线视频 |