MySQL-帶你上官網看索引

来源:https://www.cnblogs.com/hangwei/archive/2022/12/22/16994287.html
-Advertisement-
Play Games

在我之前的一篇文章中,有引用一個討論用Hash還是Tree的問題,DB中關於查找類數據結構,除了樹,還有Hash(HashMap,HashSet)。 存儲數據結構之爭 B+樹主要是照顧磁碟IO這種特殊的性質應運而生的;然而在記憶體夠多夠大時,Hash某些時候比Tree結構有用得多。 但是Hash做索引 ...


在我之前的一篇文章中,有引用一個討論用Hash還是Tree的問題,DB中關於查找類數據結構,除了樹,還有Hash(HashMap,HashSet)。

存儲數據結構之爭

B+樹主要是照顧磁碟IO這種特殊的性質應運而生的;然而在記憶體夠多夠大時,Hash某些時候比Tree結構有用得多。

但是Hash做索引的缺點也非常明顯:

1,Hash衝突造成的散列不均勻,線性查找浪費時間;

2,不支持範圍查詢,避免不了全表掃描;

3,記憶體空間要求高。

MySQL中,InnoDB和MyISAM預設的索引是B+ Tree索引;Memory則同時支持Hash和Tree索引(可在創建時直接指定使用何種索引,具體移步)。

同時,Memory這種存儲引擎“斷電即毀”的特性也不再推薦使用。

 

B樹和B+樹之爭

前置知識:知道mysql中索引即數據,數據即索引(頁的存儲結構);知道為何採用B樹(多路平衡查找樹),知道為何實際採用了B+樹。

1,B+樹空間利用率更高。B+樹只在葉子節點存儲實際數據,非葉子節點,B+樹有了更多的空間存儲索引,這樣B+樹越靠近矮胖,IO減少,

      磁碟讀寫代價低,檢索效率變高。

2,B+樹查詢效率更穩定。B+樹的檢索,任何檢索路徑都需要從根節點到葉子節點(只有葉子節點有數據),時間複雜度固定在O(LogN);

      B樹則在O(1)和O(LogN)之間。即二分查找。

3,B+樹範圍查詢性能更優。 B+樹的葉子節點使用了雙向鏈表連接在一起,而且是嚴格的順序存儲,從左到右從小到大。

4,B+樹由於葉子節點使用了鏈表進行串聯,除了支持隨機檢索,還支持順序檢索。

 

一些常見概念

回表: 查詢計劃不是使用主鍵索引,即通過二級索引查找目標;而二級索引的B+樹只存儲了主鍵數據(索引列,主鍵),

            如仍需要其它數據,需要再次根據主鍵去主鍵索引所在B+樹查找一次數據的過程,即回表。

回表引發的問題:某些情況,使用了索引,但仍然觸發了全表掃描(explain type='All')。因為此時查詢優化器對比了回表IO次數和全表掃描的IO次數,選擇了全表掃描。

 

MRR:MRR全稱:Multi-Range Read Optimization(多範圍讀取優化),動機是減少隨機磁碟訪問的次數,實現對基表數據的更順序掃描。

            官網的解釋在這。即把隨機磁碟讀轉化為順序磁碟讀,提高查詢性能(磁頭運動&磁碟預讀)。本質在做一件以空間換時間的事情。

下麵這個圖很形象借用一下:(紅線表示查詢路線,藍線表示磁碟/磁頭運動路線)

未開啟MRR:

開啟MRR:

 

上面的圖來自文章MySQL的MRR到底是什麼?

以空間換時間,這個空間指的是記憶體,記憶體大小設置在系統變數read_rnd_buffer_size,設置請參考官網

使用SQL命令:SELECT @@optimizer_switch

查看MRR是否已開啟(預設開啟)

 

索引覆蓋:查詢目標可直接從葉子節點獲取數據,不需要回表,即為索引覆蓋。

如下圖:country_id是二級索引,查找目標剛好只查詢主鍵索引和二級索引鍵值本身,直接使用二級索引的B+樹就能查到。不需要回表,稱為索引覆蓋。

 

 

 

最左匹配原則(多列索引): 官網的解釋在這裡

舉例:

有組合索引信息如下:

 

 則驗證的關鍵原則是:

-- 最左匹配原則要點:
-- 1,組合索引第一列(最左)作為第一個條件,只有接or不走索引,其它情況全部走索引;
-- 2,不以最左作為第一個條件,一般都不會走索引,唯有把組合索引條件都加上才會走(內部優化)。
explain select * from staff where first_name='Mike'; -- yes
explain select * from staff where last_name='Hillyer'; -- no
explain select * from staff where first_name='Mike' and last_name='Hillyer'; -- yes
explain select * from staff where last_name='Hillyer' and first_name='Mike'; -- yes(內部優化)
explain select * from staff where first_name='Mike' or last_name='Hillyer'; -- no
explain select * from staff where first_name='Mike' and(last_name='Hillyer' or last_name=''); -- yes

 

索引(條件)下推:即ICP,全稱是Index Condition Pushdown Optimization,官網的解釋在這裡。我們一般叫索引下推,其實正式應該稱為:索引條件下推。

怎麼理解?下推什麼呢? 顧名思義,Condition Pushdown,把查詢條件往下推。官網的這句:

With ICP enabled, ... , the MySQL server pushes this part of the WHERE condition down to the storage engine. 

翻譯即是:ICP啟用後,把where條件的部分從server層下推到storage engine層。

需要先瞭解MySQL的大概架構:

 

就是,原來where條件篩選在Server層這裡,現在下推到存儲引擎層去。

舉例:

下表中,id是主鍵,name,age是聯合索引。

查找姓張且年齡是10歲的記錄:select * from tuser where name like '張%' and age=10;

 

沒有使用ICP:二級索引找到主鍵1和4,分別回表去查找對應的完整記錄,Server層再根據where條件的age=10進行篩選。這個過程要回表兩次。

使用ICP:       二級索引找到主鍵1和4,存儲引擎層(Server的下層)根據聯合索引where條件age=10進行篩選。根據篩選結果再回表查到完整記錄。這個過程回表1次。

上面的ICP舉例和圖片出自這裡

使用執行計劃分析時,使用索引下推在Extra欄位會出現:Using index condition信息,具體參見。 

MySQL預設啟用索引(條件)下推。系統設置變數為:index_condition_pushdown 

 

避免全表掃描:官網的解釋在這裡。 

使用查詢計劃分析時,對於大型表,應儘力避免type=All的情況。 表掃描非常昂貴。

 

本文閱讀MySQL文檔為5.7。

下一篇繼續探索索引優化部分。 


作者:hangwei
出處:http://www.cnblogs.com/hangwei/
關於作者:專註於開源平臺,分散式系統的架構設計與開發、資料庫性能調優等工作。如有問題或建議,請多多賜教!
版權聲明:本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。
如果您覺得文章對您有幫助,可以點擊文章右下角“推薦”一下。您的鼓勵是作者堅持原創和持續寫作的最大動力!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 研發少閑月,九月人倍忙。又到了一年一度的“金九銀十”秋招季,又到了寫簡歷的時節,如果你還在用傳統的Word文檔尋找模板,然後默默耕耘,顯然就有些落後於時代了,本次我們嘗試使用雲平臺flowcv高效打造一份巧如範金、精比琢玉的高品質Golang技術簡歷。 首先來到雲平臺:flowcv.com 點擊 t ...
  • 整理 | 鄭麗媛,出品 | CSDN(ID:CSDNnews) 在近幾年的大環境影響下,線上筆試/面試愈發流行,這也給了部分人“鑽空子”的機會——除了筆試作弊(上網搜代碼),現在連面試都能找“替身”作弊了。 下麵,就例舉幾個真實發生的事件。 面試的人≠入職的人 最近,美國紐約州一家機構的 IT 部門 ...
  • 一、前言 程式猿為什麼如此執著於造輪子?MyBatis-Plus如此強大的工具流行這麼多年了,我為啥還在重覆造這樣的輪子? 1、公司的技術規範不允許使用MyBatis-Plus,咱也不知道什麼原因; 3、以前使用SpringDataJpa慣了,今年第一次用MyBatis,必須把它打造成我想要的樣子; ...
  • 繼我關註很久一位編程的大牛發佈了他的那篇文章——<探究:普通人都是怎麼入門編程>https://www.cnblogs.com/liuyangfirst/p/16991386.html我先去再相關評論里看到了有人說這是AI寫的一樣,不過我對這篇文章的作者稍微有些瞭解,可能就是他寫的,因為有時候你看不 ...
  • 大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家介紹的是恩智浦全系列MCU(包含Kinetis, LPC, i.MXRT, MCX)的GPIO電平中斷設計差異。 在痞子衡舊文 《以i.MXRT1xxx的GPIO模塊為例談談中斷處理函數(IRQHandler)的標準流程》里,痞子衡主要介紹得是 ...
  • 初識 Linux Shell 本書學習的第一步,就是要找到 Linux 終端的所在位置。目前較常見的圖形化終端有 Konsole、Gnome terminal、xterm 等幾種。一般安裝後在各個發行版的菜單中搜索即可找到。Gnome terminal 和 Konsole 基本是當前各大流行 Lin ...
  • 說明 基於微服務項目,產生的的多項目倉庫管理腳本。可直接保存 shell 腳本後酌情修改後試用 目錄結構 xxxx Xxx1Api/ Xxx2Api/ git_clone_api.sh git_branch_dev.sh git_pull_all.sh git_status.sh api-build ...
  • GreatSQL社區原創內容未經授權不得隨意使用,轉載請聯繫小編並註明來源。 GreatSQL是MySQL的國產分支版本,使用上與MySQL一致。 作者:KAiTO 文章來源:社區原創 往期回顧: 圖文結合帶你搞懂MySQL日誌之Redo Log(重做日誌) 圖文結合帶你搞懂InnoDB MVCC ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...