最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL 索引分類、最左匹配與失效場景問題分析

 更新時間:2026年05月19日 09:11:34   作者:fengxin_rou  
文章主要介紹了索引的概念、分類及應用,索引類似書籍目錄,能提高查詢效率,分類方面,文章詳細解析了B+樹索引的特點及其主鍵索引和二級索引的區(qū)別,并舉例說明了索引的使用場景及失效情況,強調了最左匹配原則的重要性,感興趣的朋友跟隨小編一起看看吧

索引是什么?有什么好處?

索引類似與書籍的目錄,從全表掃描改成了根據索引查找,提高了查找效率

  • 如果查詢的時候,沒有用到索引就會全表掃描,這時候查詢的時間復雜度是 O(N)
  • 如果用到了索引,那么查詢的時候,可以基于二分查找算法,通過索引快速定位到目標數據,MySQL 索引的數據結構一般是 B+ 樹,其搜索復雜度為 O(logdN),其中 d 表示節(jié)點允許的最大子節(jié)點個數。

講講索引的分類是什么?

MySQL的索引可以分為4類:

數據結構:B+Tree索引、Hash索引、Full-text索引

物理存儲:聚簇索引(主鍵索引)、輔助索引(二級索引)

字段特性:主鍵索引、唯一索引、前綴索引、普通索引

字段個數:單列索引、復合索引(又叫聯合索引)

按數據結構分

分為B+Tree索引、Hash索引、Full-text索引

B+Tree索引

. 對于 InnoDB 的聚簇索引 (Clustered Index)

  • 非葉子節(jié)點:存儲索引鍵值(比如主鍵ID)和指向下一層節(jié)點的指針。
  • 葉子節(jié)點:存儲完整的行數據(所有列的值)。
  • 一句話找到葉子節(jié)點,就找到了整行數據。
對于 InnoDB 的二級索引 (Secondary Index)
  • 非葉子節(jié)點:存儲索引鍵值(比如 name 列的值)和指向下一層節(jié)點的指針。
  • 葉子節(jié)點:存儲索引鍵值name 的值)和對應的主鍵值(不是完整行數據)。
  • 一句話找到葉子節(jié)點,只得到主鍵值,還需要回表查詢聚簇索引才能拿到完整行數據。

Hash索引底層是Hash表也就是一個一個鍵值對,在查找單個元素很快,接近O(1),并且只能做精確查找

Full-text索底層是倒排索引,使用于搜索引擎,根據詞去定位文檔,根據值去定位id。

后面兩個索引都屬于二級索引也就是輔助索引

這里介紹一下什么是倒排索引,倒排索引就是“根據關鍵詞(詞)查找其所在位置(文檔ID/行)”的映射表,與“根據文檔找詞”的正排相反。

特性Hash 索引Full-Text 索引
核心設計精確匹配(等值查詢)自然語言搜索(關鍵詞匹配)
典型查詢WHERE col = "abc"WHERE MATCH(col) AGAINST("關鍵詞")
不支持范圍查詢(><、BETWEEN
模糊查詢(LIKE
普通的 = 或 LIKE 查詢(效率極低)
底層算法哈希表倒排索引(Inverted Index)
主要用途高性能的簡單鍵值查詢搜索引擎風格的內容搜索
引擎支持主要是 Memory 引擎僅 InnoDB、MyISAM 引擎

默認引擎InnoDB在建表時會根據不同場景來選擇索引鍵

1.在建表時如果有主鍵,那么會選擇主鍵來作為聚簇索引

2.如果沒有主鍵,會選擇第一個不為NULL值的唯一列來作為聚簇索引

3.如果兩個都沒有,InnoDB會創(chuàng)建一個默認的自增id來作為聚簇索引

注意:創(chuàng)建的主鍵索引和二級索引默認使用的是 B+Tree 索引。

按物理存儲分

分為聚簇索引(主鍵索引)、輔助索引(二級索引)

這里的物理存儲是指存儲數據的方式:

  • 主鍵索引的 B+Tree 的葉子節(jié)點存放的是實際數據,所有完整的用戶記錄都存放在主鍵索引的 B+Tree 的葉子節(jié)點里;
  • 二級索引的 B+Tree 的葉子節(jié)點存放的是主鍵值,而不是實際數據。

在查詢時使用了二級索引,如果查詢的數據能在二級索引里查詢的到,那么就不需要回表,這個過程就是覆蓋索引。如果查詢的數據不在二級索引里,就會先檢索二級索引,找到對應的葉子節(jié)點,獲取到主鍵值后,然后再檢索主鍵索引,就能查詢到數據了,這個過程就是回表。

按字段特性分

分為主鍵索引、唯一索引、前綴索引、普通索引

故名思意就是有主鍵的索引,唯一列需要的索引,只用前綴就可以建立的索引、普通沒有特點但需要快速查詢的列需要的索引

主鍵索引創(chuàng)建(PRIMARY KEY):

主鍵索引就是建立在主鍵字段上的索引,通常在創(chuàng)建表的時候一起創(chuàng)建,一張表最多只有一個主鍵索引,索引列的值不允許有空值。

CREATE TABLE table_name  (
  ....
  PRIMARY KEY (index_column_1) USING BTREE
);

唯一索引創(chuàng)建(UNIQUE KEY)

唯一索引建立在 UNIQUE 字段上的索引,一張表可以有多個唯一索引,索引列的值必須唯一,但是允許有空值。

CREATE TABLE table_name  (
  ....
  UNIQUE KEY(index_column_1,index_column_2,...) 
);

建表后,如果要創(chuàng)建唯一索引,可以使用這面這條命令:

CREATE UNIQUE INDEX index_name
ON table_name(index_column_1,index_column_2,...);
  • 普通索引

普通索引就是建立在普通字段上的索引,既不要求字段為主鍵,也不要求字段為 UNIQUE。

在創(chuàng)建表時,創(chuàng)建普通索引的方式如下:

CREATE TABLE table_name  (
  ....
  INDEX(index_column_1,index_column_2,...) 
);

建表后,如果要創(chuàng)建普通索引,可以使用這面這條命令:

CREATE INDEX index_name
ON table_name(index_column_1,index_column_2,...);
  • 前綴索引

前綴索引是指對字符類型字段的前幾個字符建立的索引,而不是在整個字段上建立的索引,前綴索引可以建立在字段類型為 char、 varchar、binary、varbinary 的列上。

使用前綴索引的目的是為了減少索引占用的存儲空間,提升查詢效率。

在創(chuàng)建表時,創(chuàng)建前綴索引的方式如下:

CREATE TABLE table_name(
    column_list,
    INDEX(column_name(length))
);

建表后,如果要創(chuàng)建前綴索引,可以使用這面這條命令:

CREATE INDEX index_name
ON table_name(column_name(length));

這里可以舉例說明

-- 你的查詢

SELECT * FROM articles WHERE content = 'apple';

數據庫使用前綴索引的查找步驟:

  • 計算查詢值的前綴:取 'apple' 的前 N 個字符 → 'app'(假設前綴長度是3)
  • 在索引中找 'app':定位到索引中 'app' 這個鍵
  • 拿到對應的主鍵列表:上面例子中 'app' 對應 ID 1, 2, 3
  • 回表查完整數據:去聚簇索引拿 ID 1, 2, 3 的完整行
  • 再過濾一遍:只返回 content 完整值 真正等于 'apple' 的那一行(ID 1)

按字段個數分類

分為單列索引、聯合索引(復合索引)。

  • 建立在單列上的索引稱為單列索引,比如主鍵索引;
  • 建立在多列上的索引稱為聯合索引;

通過將多個字段組合成一個索引,該索引就被稱為聯合索引。

比如,將商品表中的 product_no 和 name 字段組合成聯合索引(product_no, name),創(chuàng)建聯合索引的方式如下:

CREATE INDEX index_product_no_name ON product(product_no, name);

這里重點講解一下復合索引,底層在葉子節(jié)點是雙向鏈表

在查找時可以看到,聯合索引的非葉子節(jié)點用兩個字段的值作為 B+Tree 的 key 值。當在聯合索引查詢數據時,先按 product_no 字段比較,在 product_no 相同的情況下再按 name 字段比較。

也就是說,聯合索引查詢的 B+Tree 是先按 product_no 進行排序,然后再 product_no 相同的情況再按 name 字段排序。

最左匹配原則

即先按照索引最左邊的列進行排序,再按后面的排序,如果不遵循這個原則,就無法使用聯合索引

比如,如果創(chuàng)建了一個 (a, b, c) 聯合索引,如果查詢條件是以下這幾種,就可以匹配上聯合索引:

  • where a=1;
  • where a=1 and b=2 and c=3;
  • where a=1 and b=2;
  • where b=2 and a=1 and c=3;
  • 需要注意的是,因為有查詢優(yōu)化器,所以 a 字段在 where 子句的順序并不重要。

但是,如果查詢條件是以下這幾種,因為不符合最左匹配原則,所以就無法匹配上聯合索引,聯合索引就會失效:

  • where b=2;
  • where c=3;
  • where b=2 and c=3;
  • 上面這些查詢條件之所以會失效,是因為(a, b, c) 聯合索引,是先按 a 排序,在 a 相同的情況再按 b 排序,在 b 相同的情況再按 c 排序。所以,b 和 c 是全局無序,局部相對有序的,這樣在沒有遵循最左匹配原則的情況下,是無法利用到索引的。

還有一種是通過a,b,c三列建造的索引,where a = 1,b = 2,c = 3,d = 4時只有前面三個能用

  • a=1 → 用到索引(最左前綴,精準定位)
  • b=2 → 用到索引(等值查詢,在 a 相同的基礎上 b 有序)
  • c=3 → 用到索引(等值查詢,在 a、b 都相同的基礎上 c 有序)
  • d=4 → 用不到索引,因為索引里根本沒有 d 這一列

失效情況

聯合索引的最左匹配原則在從左到右的查詢如果遇到了范圍查詢,在范圍查詢之后就會停止。

這里舉例說明一下

假設聯合索引是 (a, b, c, d),查詢條件是:

WHERE a = 1 AND b > 2 AND c = 3 AND d = 4

此時的匹配情況是:

  • a = 1 → 用到索引(等值,精準定位)
  • b > 2 → 用到索引(范圍查詢,走索引確定范圍的起止邊界)
  • c = 3 → 用不到索引的 B+Tree 有序性,因為 b 是范圍查詢,b 相同值的內部 c 才有序,跨 b 范圍后 c 就無序了
  • d = 4 → 同樣用不到

結論:a 和 b 兩個字段用到了索引,c 和 d 沒用到。b = 2這種條件才能保證后續(xù)有序,再b > 2就不一定有序了

聯合索引 (a, b, c, d) 的排序邏輯是:

  • 先按 a 排序
  • a 相同的情況下,按 b 排序
  • b 相同的情況下,按 c 排序
  • c 相同的情況下,按 d 排序

舉個例子:

(a=1, b=3, c=1)
(a=1, b=3, c=5)
(a=1, b=4, c=2)  <-- 注意這里,b值變了
(a=1, b=4, c=8)
(a=1, b=5, c=3)  <-- c=3 在這里

到此這篇關于MySQL 索引分類、最左匹配與失效場景問題分析的文章就介紹到這了,更多相關mysql索引分類最左匹配內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • MySQL優(yōu)化總結-查詢總條數

    MySQL優(yōu)化總結-查詢總條數

    這篇文章主要介紹了MySQL優(yōu)化總結-查詢總條數的相關內容,文中進行簡單的測試對比,具有一定參考價值,需要的朋友可以了解下。
    2017-10-10
  • MySQL中實現刪除表的完整指南

    MySQL中實現刪除表的完整指南

    本文詳細解析了MySQL中DROP?TABLE語句的基礎語法和高級用法,包括單表/多表刪除,IF?EXISTS安全機制,外鍵約束處理等,感興趣的小伙伴可以跟隨小編一起學習一下
    2026-02-02
  • Windows中MySQL root用戶忘記密碼解決方案

    Windows中MySQL root用戶忘記密碼解決方案

    在實際應用中,經常會出現忘記mysql管理員用戶root的密碼的情況出現,那么我們如何來設置一個新密碼從而登錄數據庫呢,下面我們來探討下
    2014-07-07
  • MySQL常見的底層優(yōu)化操作教程及相關建議

    MySQL常見的底層優(yōu)化操作教程及相關建議

    這篇文章主要介紹了MySQL常見的底層優(yōu)化操作教程及相關建議,包括對運行操作系統的硬件方面及存儲引擎參數的調整等零碎方面的小整理,需要的朋友可以參考下
    2015-12-12
  • MYSQL配置參數優(yōu)化詳解

    MYSQL配置參數優(yōu)化詳解

    MySQL是優(yōu)化難度最大的一個部分,不但需要理解一些MySQL專業(yè)知識,同時還需要長時間的觀察統計并且根據經驗 進行判斷,然后設置合理的參數。下面我們了解一下MySQL優(yōu)化的一些基礎
    2018-07-07
  • MySQL主從同步的幾種實現方式

    MySQL主從同步的幾種實現方式

    本文主要介紹了MySQL主從同步的幾種實現方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-02-02
  • MYSQL表中某字段所有值大小寫轉換

    MYSQL表中某字段所有值大小寫轉換

    這篇文章主要為大家介紹了MYSQL表中某字段所有值大小寫轉換示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • 計算機二級考試MySQL??键c 8種MySQL數據庫設計優(yōu)化方法

    計算機二級考試MySQL常考點 8種MySQL數據庫設計優(yōu)化方法

    這篇文章主要為大家詳細介紹了計算機二級考試MySQL??键c,詳細介紹8種MySQL數據庫設計優(yōu)化方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • 一文了解MySQL二級索引的查詢過程

    一文了解MySQL二級索引的查詢過程

    索引是一種用于快速查詢行的數據結構,就像一本書的目錄就是一個索引,下面這篇文章主要給大家介紹了關于MySQL二級索引查詢過程的相關資料,需要的朋友可以參考下
    2022-02-02
  • mysql超大分頁優(yōu)化的實現

    mysql超大分頁優(yōu)化的實現

    本文介紹了MySQL中處理超大分頁查詢的優(yōu)化方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-12-12

最新評論

芜湖市| 邢台县| 彭泽县| 嘉善县| 买车| 渭南市| 横峰县| 兰西县| 东城区| 衡水市| 昭通市| 桐乡市| 小金县| 孙吴县| 水城县| 蕉岭县| 梨树县| 漳平市| 阳江市| 江永县| 南溪县| 喜德县| 印江| 桃园市| 新和县| 彰化县| 吉木乃县| 特克斯县| 甘肃省| 巴彦淖尔市| 福海县| 廉江市| 德安县| 成武县| 平塘县| 汉沽区| 冷水江市| 平武县| 华容县| 兰坪| 临湘市|