Mysql索引一篇就夠了

索引

定義

索引是對數據庫表中一列或者多列的值進行排序的結構。

目的

數據庫索引好比一本書的目錄,提高查詢效率。但是為表設置索引要付出相應的代價:

  • 增加了數據庫的存儲空間
  • 在插入和修改時需花費更多的時間(因為索引也要隨之變動)

分類

1. 聚集索引

索引項的順序與表中記錄的物理順序一致。對于聚集索引,葉子結點即存儲其真實的數據行,不再有另外單獨的數據頁。

2. 非聚集索引

表數據存儲順序與索引順序無關。對于非聚集索引,葉子結點包含索引字段值和數據頁數據行的地址,其行數量與數據表中行數量一致。

注意:一個表中只有一個聚集索引,但是可以有多個非聚集索引。

3. 唯一索引

不允許具有索引值相同的行,但是可以為 NULL,不能有多個 NULL。

4. 主鍵索引

是唯一索引的特殊類型。數據庫表中經常有一列或多列組合,其值唯一標識表中的每一行,該列稱為表的主鍵。

在數據庫中為表定義主鍵將自動創建主鍵索引。

索引存儲結構

B 樹

對于 m 階 B 樹,有如下性質:

  • 根節點至少有 2 個孩子節點

  • 樹中每個節點最多含有 m 個孩子(m >= 2)

  • 除根節點、葉子節點外其他節點至少有 ceil(m/2) 個孩子

  • 所有葉子節點都在同一層

  • 假設每個非終端節點中包含 n 個關鍵字信息,其中

    a)Ki(i=1..n)為關鍵字,being且找順序升序排序 K(i-1) < Ki

    b)關鍵字的個數 n 必須滿足:ceil(m/2)-1 <= n <= (m-1)

    c)非葉子節點的指針:P[1],P[2],... ,P[M];其中 P[1] 指向關鍵字小于 K[1] 的子樹,P[M] 指向關鍵字大于 K[M-1] 的子樹,其他 P[i] 關鍵字屬于(K[i-1],K[i]) 的子樹

alt

B+ 樹

B+ 樹是 B 樹的變體,其定義基本與 B 樹相同,除了:

  • 非葉子節點的子樹指針和關鍵字個數相同

  • 非葉子節點的子樹指針 P[i],指向關鍵字值 [K[i],K[i+1]) 的子樹

  • 非葉子節點僅用來索引,數據都保存在葉子節點

  • 所有葉子節點均有一個鏈指針指向下一個葉子節點

alt

數據庫系統普遍采用 B+ 樹作為索引結構,主要有以下原因:

  • B+ 樹的磁盤讀寫代價更低

    因為非葉子結點只存儲索引信息,其內部節點相同 B 樹更小,如果把 key 存入同一盤塊中,盤塊所能包含的 key 越多,一次性讀入內存中需要查找的 key 就越多,相對來說磁盤的 I/O次數就減少了。

    舉個例子:假設磁盤中的一個盤塊容納 16 字節,而一個 key 占 2 字節,一個 key 具體信息指針占 2 字節。一棵 9 階 B 樹(一個結點最多 8 個關鍵字)的內部結點需要 2 ( (8*(2+2) / 16 = 2)個盤塊。B+ 樹內部結點只需要 1 (8 * 2 / 16 = 1)個盤塊。當需要把內部結點讀入內存中的時候,B 樹就比 B+ 樹多 1 次盤塊查找時間。

  • B+ 樹的查詢效率更加穩定

    由于非葉子結點并不是最終指向文件內容的結點,而只是葉子結點中關鍵字的索引。所以任何關鍵字的查找必須走一條從根結點到葉子結點的路。所有關鍵字查詢的路徑長度相同,導致每一個數據的查詢效率相當。

  • B+ 樹更有利于對數據庫的掃描

    B+ 樹只要遍歷葉子結點就可以遍歷到所有數據。

HASH

哈希索引就是采用一定的哈希算法,把鍵值換算成新的哈希值,檢索時不需要類似 B+ 樹那樣從根節點到葉子節點逐級查找,只需一次哈希算法即可立刻定位到相應位置,速度非常快

哈希索引底層的數據結構是哈希表,能以 O(1) 時間進行查找,但是失去了有序性;因此在絕大多數需求為單條記錄查詢的時候,可以選擇哈希索引,查詢性能最快。

哈希索引的不足:

  • 無法用于排序與分組
  • 只支持 精確查找,無法用于部分查找和范圍查找
  • 不能避免全表掃描
  • 遇到大量 Hash 沖突的情況效率會大大降低

索引的物理存儲

MySQL 索引使用的是 B 樹中的 B+ 樹,但索引是在存儲引擎層實現的,而不是在服務器層實現的,所以不同存儲引擎具有不同的索引類型和實現。

MyISAM 索引存儲機制

MyISAM 引擎使用 B+ 樹作索引結構,葉子節點的 data 域存放的是數據記錄的地址,所有索引均是非聚集索引。

alt

上圖是一個 MyISAM 表的主索引(Primary key)示意圖。

假設該表一共有三列,以 Col1 為主鍵。MyISAM 的索引文件僅僅保存數據記錄的地址。

在 MyISAM 中,主索引和輔助索引(Secondary key)在結構上沒有任何區別,只是主索引要求 key 是唯一的,而輔助索引的 key 可以重復。如果在 Col2 上建立一個輔助索引,則該輔助索引的結構如下:

alt

同樣也是一棵 B+ 樹,data 域保存數據記錄的地址。

MyISAM 中首先按照 B+ 樹搜索算法搜索索引,如果指定的 key 存在,則取出其 data 域的值,然后以 data 域的值為地址,讀取相應數據記錄。 MyISAM 的索引方式也叫做非聚集索引(稀疏索引)(索引和數據是分開存儲的)。

InnoDB 索引存儲機制

InnoDB 也使用 B+ 樹作為索引結構。有且僅有一個聚集索引,和多個非聚集索引。

InnoDB 的數據文件本身就是索引文件。MyISAM 索引文件和數據文件是分離的,索引文件僅保存數據記錄的地址。而在 InnoDB 中,表數據文件本身就是按 B+ 樹組織的一個索引結構,這棵樹的葉子節點 data 域保存了完整的數據記錄。這個索引的 key 是數據表的主鍵,因此 InnoDB 表數據文件本身就是主索引

alt

上圖是 InnoDB 主索引(同時也是數據文件)的示意圖。可以看到葉子節點包含了完整的數據記錄。

這種索引叫做聚集索引(密集索引)(索引和數據保存在同一文件中):

  • 若一個主鍵被定義,該主鍵作為聚集索引;
  • 若沒有主鍵定義,該表的第一個唯一非空索引作為聚集索引;
  • 若均不滿足,則會生成一個隱藏的主鍵( MySQL 自動為 InnoDB 表生成一個隱含字段作為主鍵,這個字段是遞增的,長度為 6 個字節)。

與 MyISAM 索引的不同是 InnoDB 的輔助索引 data 域存儲相應記錄主鍵的值而不是地址。例如,定義在 Col3 上的一個輔助索引:

alt

聚集索引這種實現方式使得按主鍵的搜索十分高效,但是輔助索引搜索需要檢索 2 遍索引:

首先檢索輔助索引獲得主鍵,然后用主鍵到主索引中檢索獲得記錄。

注意 InnoDB 索引機制中:

  • 不建議使用過長的字段作為主鍵,因為所有輔助索引都引用主索引,過長的主索引會令輔助索引變得過大。

  • 不建議用非單調的字段作為主鍵,因為 InnoDB 數據文件本身是一棵 B+ 樹,非單調的主鍵會造成在插入新記錄時數據文件為了維持 B+ 樹的特性而頻繁的分裂調整,十分低效。

    使用自增字段作為主鍵則是一個很好的選擇。

索引的優點

  • 大大減少了服務器需要掃描的數據行數。
  • 幫助服務器避免進行排序和分組,以及避免創建臨時表(B+Tree 索引是有序的,可以用于 ORDER BY 和 GROUP BY 操作。臨時表主要是在排序和分組過程中創建,不需要排序和分組,也就不需要創建臨時表)。
  • 將隨機 I/O 變為順序 I/O(B+Tree 索引是有序的,會將相鄰的數據都存儲在一起)。

建索引的原則

  • 最左前綴匹配原則

    MySQL 會一直向右匹配知道遇到范圍查詢(>、<、between、like)就停止匹配。比如 a=3 and b=4 and c>5 and d=6,如果建立 (a,b,c,d) 順序的索引,d 就是用不到索引的,如果建立(a,b,d,c) 的索引則都可以用到,并且 a,b,d 的順序可以任意調整。

  • = 和 in 可以亂序

    比如 a = 1 and b = 2 and c = 3建立 (a,b,c) 索引可以任意順序,MySQL 的查詢優惠器可進行優化。

  • 盡量選擇選擇度高的列建索引

    #?選擇度計算
    SELECT?COUNT(DISTINCT?staff_id)/COUNT(*)?AS?staff_id_selectivity,
    COUNT(DISTINCT?customer_id)/COUNT(*)?AS?customer_id_selectivity,
    COUNT(*)
    FROM?payment;
  • 使用 like 進行模糊查詢時,如果已經建立索引,第一個位置不要使用 '%',否則索引會失效。

  • 當檢索性能遠遠大于檢索性能時,不應該建立索引。

索引失效

  • 最左前綴匹配原則,遇到范圍查詢

  • like 模糊查詢,第一個位置使用 '%'

  • 沒有查詢條件

  • 表比較小時,全表掃描速度比索引速度快時,索引失效

    (由于索引掃描后要利用索引中的指針去逐一訪問記錄,假設每個記錄都使用索引訪問,則讀取磁盤的次數是查詢包含的記錄數T,而如果表掃描則讀取磁盤的次數是存儲記錄的塊數B,如果T>B 的話索引就沒有優勢了。)

本文由 mdnice 多平臺發布

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/211832.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/211832.shtml
英文地址,請注明出處:http://en.pswp.cn/news/211832.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

一、C#筆記

1.注釋 /*多行注釋*/class HelloWorld{ void Hello(){Console.WriteLine("Hello!");//單行注釋}} 2.理解語句 2.1方法、語法、語義 2.2使用標識符 標識符語法規則&#xff1a; 只能使用字母&#xff08;大寫和小寫&#xff09;、數字和下劃…

C++相關閑碎記錄(5)

1、容器提供的類型 2、Array Array大小固定&#xff0c;只允許替換元素的值&#xff0c;不能增加或者移除元素改變大小。Array是一種有序集合&#xff0c;支持隨機訪問。 std::array<int, 4> x; //elements of x have undefined value std::array<int, 5> x {…

滲透測試——七、網站漏洞——命令注入和跨站請求偽造(CSRF)

滲透測試 一、命令注入二、跨站請求偽造(CSRF)三、命令注入頁面之注人測試四、CSRF頁面之請求偽造測試 一、命令注入 命令注入(命令執行) 漏洞是指在網頁代碼中有時需要調用一些執行系統命令的函數例如 system()、exec()、shell_exec()、eval()、passthru()&#xff0c;代碼未…

基于ssm在線云音樂系統的設計與實現論文

摘 要 隨著移動互聯網時代的發展&#xff0c;網絡的使用越來越普及&#xff0c;用戶在獲取和存儲信息方面也會有激動人心的時刻。音樂也將慢慢融入人們的生活中。影響和改變我們的生活。隨著當今各種流行音樂的流行&#xff0c;人們在日常生活中經常會用到的就是在線云音樂系統…

走迷宮(詳細分析)

目錄 一、課題描述 輸入樣例&#xff1a; 輸出樣例&#xff1a; 二、需求分析 輸入的形式和輸入值的范圍&#xff1a; 輸出的形式&#xff1a; 程序所能達到的功能&#xff1a; 三、概要設計 四、流程圖 五 、代碼詳細注釋 六、測試數據和結果 一、課題描述 以一個…

freeswitch webrtc video_demo客戶端進行MCU的視頻會議

系統環境 一、編譯服務器和加載模塊 二、下載編譯指定版本video_demo 三、配置verto.conf.xml 1.修改配置文件 2.重新啟動 四、MCU通話測試 1.如何使用video_demo 2.測試結果 五、MCU的通話原理及音頻/視頻/布局/管理員等參數配置 附錄 freeswitch微信交流群 系統環境 lsb_rel…

MyBatis處理映射關系

在Mybatis實現數據處理過程中&#xff0c;字段名符合數據庫的規則&#xff0c;屬性一般為駝峰規則&#xff0c;因此字段名和屬性名通常不一致&#xff0c;此時可以通過以下兩種方式對數據庫字段進行映射處理&#xff1a; 為字段起別名&#xff0c;保證和實體類中的屬性名一致在…

lv11 嵌入式開發 IIC(下) 20

目錄 1 Exynos4412下IIC控制器介紹 1.1 總覽 1.2 特征 1.3 工作框圖 1.4 其他內容介紹 1.5 四種工作模式寄存器流程 2 IIC寄存器詳解 2.1 概述 2.2 控制寄存器 2.3 狀態寄存器 2.4 地址寄存器 2.5 數據寄存器 2.6 其他寄存器 3 MPU06050 3.1 簡介 3.2 MPU6050主…

HJ103 Redraiment的走法

題目&#xff1a; HJ103 Redraiment的走法 題解&#xff1a; dfs 暴力搜索 枚舉數組元素&#xff0c;作為起點如果后續節點大于當前節點&#xff0c;繼續向后搜索記錄每個起點的結果&#xff0c;求出最大值 public int getLongestSub(int[] arr) {int max 0;for (int i 0…

data_loader返回的每個batch的數據大小是怎么計算得到的?

data_loader是一個通用的術語&#xff0c;用于表示數據加載器或數據批次生成器。它是在機器學習和深度學習中常用的一個概念。 一、data loader 數據加載器&#xff08;data loader&#xff09;是一個用于加載和處理數據集的工具&#xff0c;它可以將數據集劃分為小批次&#…

提示(Prompt)工程中提示詞的開發優化基礎概念學習總結

本文對學習過程進行總結&#xff0c;僅對基本思路進行說明&#xff0c;結果在不同的模型上會有差異。 提示與提示工程 提示&#xff1a;指的是向大語言模型輸入的特定短語或文本&#xff0c;用于引導模型產生特定的輸出&#xff0c;以便模型能夠生成符合用戶需求的回應。 提示…

內存學習——堆(heap)

目錄 一、概念二、自定義malloc函數三、Debug運行四、heap_4簡單分析4.1 heap管理鏈表結構體4.2 堆初始化4.3 malloc使用4.4 free使用 一、概念 內存分為堆和棧兩部分&#xff1a; 棧&#xff08;Stack&#xff09;是一種后進先出&#xff08;LIFO&#xff09;的數據結構&…

AVFormatContext封裝層:理論與實戰

文章目錄 前言一、封裝格式簡介1、FFmpeg 中的封裝格式2、查看 FFmpeg 支持的封裝格式 二、API 介紹三、 實戰 1&#xff1a;解封裝1、原理講解2、示例源碼 13、運行結果 14、示例源碼 25、運行結果 2 四、 實戰 2&#xff1a;轉封裝1、原理講解2、示例源碼3、運行結果 前言 A…

文章解讀與仿真程序復現思路——電力系統自動化EI\CSCD\北大核心《考慮電力-交通交互的配電網故障下電動汽車充電演化特性》

這個標題涉及到電力系統、交通系統和電動汽車充電的復雜主題。讓我們逐步解讀&#xff1a; 考慮電力-交通交互的配電網故障&#xff1a; 電力-交通交互&#xff1a; 指的是電力系統和交通系統之間相互影響、相互關聯的關系。這可能涉及到電力需求對交通流量的影響&#xff0c;反…

回溯算法之N皇后

一 什么是回溯算法 回溯算法&#xff08;Backtracking Algorithm&#xff09;是一種用于解決組合優化問題的算法&#xff0c;它通過逐步構建候選解并進行驗證&#xff0c;以尋找所有滿足特定條件的解。回溯算法通常應用于在給定約束條件下枚舉所有可能解的問題&#xff0c;如…

Git—文件添加查看刪除修改

目錄 1.添加文件—場景一 2.查看.git文件 3.添加文件—場景三 4.修改文件 5.版本回退 6.撤銷修改 7.刪除文件 1.添加文件—場景一 在包含.git的目錄下新建?個ReadMe文件&#xff0c;我們可以使用 git add 命令可以將文件添加到暫存 區&#xff1a; ●添加一個或多個文…

Matlab數學建模算法之小波神經網絡詳解

&#x1f517; 運行環境&#xff1a;Matlab &#x1f6a9; 撰寫作者&#xff1a;左手の明天 &#x1f947; 精選專欄&#xff1a;《python》 &#x1f525; 推薦專欄&#xff1a;《算法研究》 &#x1f510;#### 防偽水印——左手の明天 ####&#x1f510; &#x1f497; 大家…

vue的屬性

key 預期&#xff1a;number | string | boolean (2.4.2 新增) | symbol (2.5.12 新增) key 的特殊 attribute 主要用在 Vue 的虛擬 DOM 算法&#xff0c;在新舊 nodes 對比時辨識 VNodes。如果不使用 key&#xff0c;Vue 會使用一種最大限度減少動態元素并且盡可能的嘗試就地…

2022藍橋杯c組求和

題目名字 求和 題目鏈接 題意 輸入的每個數都要兩兩相乘&#xff0c;然后再加起來&#xff0c;求最后總和&#xff1b; 思路 每個數乘這個數的前綴和即可 算法一&#xff1a;前綴和 實現步驟 先把前綴和寫出來再寫for循環每個數都乘以自己的前綴和&#xff1b; 實現步驟 直接…

存儲成本降71%,怪獸充電歷史庫遷移OceanBase

怪獸充電作為共享充電寶第一股&#xff0c;業務增長迅速&#xff0c;以至于業務架構不停地增加組件。在驗證 OceanBase 可以簡化架構并帶來更大的業務價值后&#xff0c;首次嘗試在歷史庫中使用 OceanBase 替代 MySQL&#xff0c;存儲成本降低 71%。本文為怪獸充電運維架構部王…