MySQL - 4種基本索引、聚簇索引和非聚索引、索引失效情況

目錄

一、索引

1.1、簡單介紹

1.2、索引的分類

1.2.1、主鍵索引

1.2.2、單值索引(單列索引、普通索引)

1.2.3、唯一索引

1.2.4、復合索引

1.2.5、復合索引經典問題

1.3、索引原理

1.3.1、主鍵自動排序

1.3.2、索引的底層原理

1.3.3、B 樹和 B+樹的區別

1.4、聚簇索引和非聚簇索引

1.4.1、innoDB 中的主鍵索引

1.4.2、使用聚簇索引的優勢

1.4.3、使用聚簇索引需要注意什么

1.4.4、為什么主鍵通常建議使用自增 id

1.5、索引失效的場景


一、索引


1.1、簡單介紹

索引就是一種幫助? mysql 提高查詢效率的數據結構.

優點:

  1. 大大增加了查詢速度.

缺點:

  1. 索引實際上是一張表,因此需要消耗一部分空間資源.
  2. 對表中的數據進行增刪改的時候,需要更新索引,因此速度會受到一定影響.

1.2、索引的分類

1.2.1、主鍵索引

實際上就是我們創建數據庫時指定的主鍵(主鍵索引值不能為空、不能重復.),會自動創建索引,叫做 “主鍵索引”,在 innodb 引擎中就是所謂的 “聚簇索引”.

例如,以 id 為主鍵建表

create table user(id int PRIMARY KEY, name varchar(20), age int);

然后通過以下命令查看 user 表的索引

show index from user;

?

1.2.2、單值索引(單列索引、普通索引)

就是為表中的某一列創建的索引,一個表中可以有多個單列索引.?

例如,表中有字段 id、name、age,那么為 其中的 name 創建一個索引,就叫單列索引.

創建方式有以下兩種:

a)建表時創建(注意,這種方式創建,索引名和字段名一致)

# 給 name 單獨創建索引
create table user(id int primary key, name varchar(20), age int, key(name));# 給 name 和 age 分別創建索引
create table user(id int primary key, name varchar(20), age int, key(name), key(age));

b)建表后創建

create table user(id int primary key, name varchar(20), age int);create index index_name on user(name);

c)刪除索引

drop index 索引名 on 表明

?

1.2.3、唯一索引

在創建表的時候,有時候我們會通過 unique 指定某個字段唯一,這個時候就會創建唯一索引.

Ps:允許有 null 值,并且可以有多個.

創建方式有以下兩種:

a)建表時指定

# 第一種寫法
create table user(id int primary key, name varchar(20) unique, age int);# 第二種寫法
create table user(id int primary key, name varchar(20), age int, unique(name));

b)建表后創建

create unique index index_name on user(name);

1.2.4、復合索引

就是我們為表中的多個字段一起創建一個索引.?

Ps:查詢時,在 where 條件后,必須要使用 and 連接復合索引字段,否則不生效.

創建方式有以下兩種:

a)建表時創建

create table user(id int primary key, name varchar(20), age int, key(name, age));

b)建表后創建

create index name_age_index on user(name, age);

1.2.5、復合索引經典問題

問題:有一個用戶表,給 name、age、gender 三個字段創建了一個復合索引 key(name, age, gender),以下場景,哪種查詢索引會生效?

以下是 where 查詢后通過 and 拼接的字段.

  1. name? ????????????????????????生效
  2. name? age? ? ? ? ? ? ? ? ? 生效
  3. name? age? gender? ? ?生效
  4. name??gender??age? ? ?生效
  5. age? gender? ? ? ? ? ? ? ? 失效
  6. gender? ? ? ? ? ? ? ? ? ? ? ? 失效
  7. gender??age??name? ? ?生效

該怎么判斷呢?符合索引生效只要滿足以下任意一個原則即可:

  1. 最左前綴元組:必須包含做前綴,也就意味著 name、 name age、name age gender 是生效的.
  2. mysql 引擎為了更好的利用索引,在查詢過程中會動態調整查詢字段順序,便于利用索引,也就意味著只要包含所有索引字段即可(任意的組合都可以).

1.3、索引原理

1.3.1、主鍵自動排序

當我創建一個 user 表(含主鍵 id),然后按照無序 id 的方式插入數據,會發現查詢結果盡然按照 主鍵 id 排序了

為什么會進行排序呢?

排序之后相對來說,查詢更快.? 例如有 10 個自增 id,現在查詢 id = 3 的,那么只需要向下對比三次即可得到,而對于無序數據來說每次都需要遍歷一遍數據才能得到.

這也就說明為啥主鍵不建議使用 uuid 去建立,而是使用 int 類型?因為在主鍵建立索引的時候,會先根據表中的主鍵去排序,排序后在查詢效率會更高.

1.3.2、索引的底層原理

假設有如下表和信息

索引的數據結構就是一個 b+ 樹,原理如下

a)排序,形成鏈表:表中的每一條數據組織成一個鏈表中的一個節點,結構由三部分構成:“主鍵 + 數據 + 指針”,數據就是表中的非主鍵索引字段(name, age),指針就是用來指向下一個節點,這些節點會現經過主鍵 id 的排序,最后組織成一個鏈表的結構,得到b+樹的葉子節點 如下

b)頁管理:將鏈表進行分頁管理,每一頁的大小默認存儲 16kb,假設如下圖(真實情況一頁存放的數據有很多).

c)頁目錄管理:將每一頁最左邊節點的主鍵 和 指針 拿出來存放到頁目錄中,頁目錄的默認大小也是 16kb

d)如果頁目錄的大小占滿了,那么可能還會繼續向上生成頁目錄(父節點),不過一般開發存儲的數據,樹的高度都不會超過 4 的,也就是說,當需要查找某一數據時,最多只需要 1~3 次 I/O? 操作(注意:頂層的根節點時在內存中的).

1.3.3、B 樹和 B+樹的區別

B+ 樹相當于是在 B 上的一種優化,主要區別如下:

  1. B+ 樹非葉子節點只存儲鍵值對信息,B 樹 data 數據也需要存儲,而每一頁的存儲空間是有限的(默認 16 kb),那么如果 data 數據較大時,每個節點能存儲的 key 就很少,進而導致樹的深度較大,增大了查詢時的磁盤 IO 次數(每一層都進行一次 IO).
  2. B+ 樹的葉子節點保存全集數據,是一個鏈表結構,而非葉子節點只存儲 key,大大增加了非葉子節點存儲 key 的數量,降低了樹高.

1.4、聚簇索引和非聚簇索引

1.4.1、innoDB 中的主鍵索引

聚簇索引:由 主鍵索引 和 輔助索引 構成.

主鍵索引:主鍵索引中,葉子節點保存表中每一行的所有數據,當需要查找例如 where Id = 14,就會去主鍵索引?B+ 樹上找到的葉子節點,然后獲取行數據.

Ps:如果沒有定義主鍵,就會選擇唯一且非空的索引代替,如果非空索引也沒有,就會自己隱式定義一個主鍵作為聚簇索引

輔助索引(innoDB 中的非聚簇索引就是輔助索引):就是在聚簇索引之上建立的索引,一般來說就是表中給其他字段建立的索引(非主鍵索引),也就是 復合索引、單列索引、唯一索引,并且的葉子節點存儲的不再是行物理地址,而是主鍵值,因此輔助索引最少需要二次查詢才能找到數據,例如 where name='cyk',步驟如下

  1. 在輔助索引 B+ 樹種檢索 name,然后到達葉子節點獲取對應的主鍵.
  2. 根據主鍵在聚簇索引 B+ 樹種在及進行一次檢索操作,最終到達葉子節點獲取整行數據.

非聚簇索引:在 myisam 使用的是非聚簇索引,也由兩顆 B+ 樹構成(主鍵索引、輔助索引),主鍵索引B+樹節點存儲了主鍵,輔助索引 B+ 樹種存儲了輔助鍵.? 葉子節點都是用一個地址指向真正的表的數據,因此輔助鍵無需像 innoDB 一樣訪問主鍵索引樹.

1.4.2、使用聚簇索引的優勢

問題:每次使用輔助索引檢索都需要經過兩次 B+ 樹查詢,看上去聚簇索引的效率明顯低于非聚簇索引,這不是多此一舉么,聚簇索引優勢在哪?

  1. 訪問同一數據也不同記錄時,會把頁加載到緩存中,再次訪問的時候,會在內存中完成訪問,不必訪問磁盤,而主鍵和數據又是一起被載入內存的,因此按照主鍵 id 來組織數據(排好序的),獲取更快.
  2. innoDB 中的輔助索引葉子節點存儲主鍵值,而不是物理地址,因此當行數據發生改變時(對表進行增刪改),葉子節點也無需像 myisam 非聚簇索引的輔助索引一樣改變地址,只需要維護索引樹即可.
  3. innoDB 中的輔助索引葉子節點存放的是主鍵值,而 myisam 中存儲的是物理地址,因此空間占用更小.

1.4.3、使用聚簇索引需要注意什么

主鍵最好不要使用 uuid,因為 uuid 值過于離散,不適合排序,并且有可能生成的 uuid 插入在索引樹的中間位置,導致樹調整復雜度變大,查詢時消耗更多的時間.

建議使用 int 或者 bigint 類型的自增,方便排序并且默認會在索引樹的末尾增加主鍵值,對索引樹的結構影響最小.

1.4.4、為什么主鍵通常建議使用自增 id

聚簇索引的數據物理地址存放順序和索引主鍵 id 順序時一致的,因此索引是相鄰的,對應的數據也是在相鄰的磁盤上. 如果主鍵不是自增 id,那么會不斷調整數據的物理地址,來進行分頁. 如果是自增,就只要一頁一頁寫,磁盤碎片也就少了.

1.5、索引失效的場景

1. 查詢語句中使用 like 關鍵字,如果匹配字符串的第一個字符為 "%",索引不會被使用;如果 "%" 不是在第一個位置,索引就會被使用.

2. 查詢語句中使用復合索引,需要滿足匹配原則才可以(上面講到過了)。

3. 查詢語句中使用 or 關鍵字時,如果 or 前后的兩個條件都是索引,那么就會使用索引,如果任意一個不是索引,那么查詢中不使用索引.??

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

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

相關文章

創作4周年

🙌秋名山碼民的主頁 😂oi退役選手,Java、大數據、單片機、IoT均有所涉獵,熱愛技術,技術無罪 🎉歡迎關注🔎點贊👍收藏??留言📝 獲取源碼,添加WX 目錄 前言機…

哈希表-set、map

當需要判斷一個元素是否在集合中時,就使用哈希法 散列表(Hash table,也叫哈希表),是根據鍵(Key)而直接訪問在內存存儲位置的數據結構。 哈希表中關鍵碼就是數組的索引下標,然后通過…

Web框架Flask

Web框架Flask Flask簡介第一個Flask應用Flask路由Flask路由變量規則Flask URL 構建Flask重定向Flask靜態文件Flask渲染模板Flask請求對象Flask響應對象Flask CookiesFlask錯誤Flask JSON 格式的 APIFlask SessionFlask 消息閃現Flask日志Flask藍圖Flask視圖Flask Jinja2 模板F…

微信消息提醒

有時候同事沒有打開微信,重要的信息可以設置提醒

app小程序開發的重點在哪里?|企業軟件定制網站建設

app小程序開發的重點在哪里?|企業軟件定制網站建設 App小程序定制開發是近年來快速發展的一項技術服務,隨著移動互聯網的普及和用戶需求的不斷升級,越來越多的企業和個人開始關注和需求定制化的小程序開發。那么,對于app小程序定制…

Springboot_文件下載功能(前端后端)

遇到的問題: 文件下載后文件一直被破壞,無法正常打開文件名亂碼,如圖 剛開始一直在糾結,是不是后端沒有寫對,然后導致下載不能使用 后來搜索了一些資料,發現后端沒什么問題 然后就開始找到其他項目對比…

頭發的方向圖(2D和3D)與合成

首先,我們從一個不受光照限制的環境中拍攝一組輸入圖像,這些圖像包含了頭發的不同視角和姿態。我們對這些圖像進行半自動的分割,將頭發從背景中分離出來,然后使用PMVS ,一種先進的多視角立體算法,來重建一個…

Qt 問題 判斷QTreeWidget的子節點的父節點是否可見

bool JudgeParentItemVisible(QTreeWidgetItem * pLayerItem) {bool bVisible true;QTreeWidgetItem * pParentItem (QTreeWidgetItem *)pLayerItem->parent(); //獲取父節點if (pParentItem ! NULL) //父節點不為空{if (pParentItem->checkState(0) Qt::CheckState::…

廣播組播、本地套接字通信、wireshark、以太網幀格式、三次握手四次揮手

廣播(使用 UDP 套接字) 廣播地址:主機號最大的地址。 廣播:給所在局域網的所有主機發送數據報。(之前的數據報發送方式是單播。) 以下情況中使用廣播: 局域網 搜索協議。 比如家中的智能產品&a…

局域網共享打印機共享,簡單至簡至一鍵處理011bDll等問題

一、電腦系統是否激活(可選) 二、確保主客戶端PC在同一局域網內(可選) 可以通過ping 目標地址 如ping 192.168.1.202;看是否可以正常通信 下面是惠普類型打印機共享問題關鍵(文本記得保存) …

Redisson 分布式鎖的最佳實踐

Redisson 分布式鎖的最佳實踐 第一、添加依賴第二、添加redisson配置類第三、添加測試類測試結果擴展知識redisson鎖中lock方法和tryLock方法有什么區別鎖續約 注意事項 引言 在現代分布式系統中,處理并發問題是至關重要的。分布式鎖是解決這類問題的關鍵工具之一。…

雙11再創新高!家電行業如何通過矩陣管理,賦能品牌增長?

雙11大促已落下帷幕,雖然今年不再戰報滿天飛,但從公布的數據來看,家電行業整體表現不俗。 根據抖音電商品牌業務發布的收官戰報,家電行業創造了成交新紀錄,整體同比增長125%。快手官方數據顯示,消電家居行業…

深入理解JMM以及并發三大特性(1)

文章目錄 1. 并發與并行2. JMM3. 并發三大特性4.總結 1. 并發與并行 并行:指在同一時刻,有多條指令在多個處理器上同時執行。所以無論從微觀還是宏觀來看,二者都是一起執行的。 并發:指在同一時刻只能有一個指令執行,…

基于springboot實現校園在線拍賣系統項目【項目源碼】

基于springboot實現校園在線拍賣系統演示 Javar技術 JavaScript是一種網絡腳本語言,廣泛運用于web應用開發,可以用來添加網頁的格式動態效果,該語言不用進行預編譯就直接運行,可以直接嵌入HTML語言中,寫成js語言&…

java開發中各個環境的適用場景

java開發中各個環境的適用場景 一.開發環境 在系統開發的經典模型,一般會分成 2 類 5 種環境: 【線下】本地環境(local)、開發環境(dev)、測試環境(test) 【線上】預發布環境(stage)、生產環境(prod) 每個環境、每個項目使用獨立的二級域名 線下、線…

Modbus轉Profinet改變局面,PLC與電力儀表秒級響應

Modbus轉Profinet改變了傳統的局面,實現了PLC與電力儀表之間的秒級響應。在過去,由于Modbus通信協議的限制,PLC與電力儀表之間的數據傳輸速度受到了很大的限制,無法滿足工業自動化領域對實時性的要求。然而,隨著Modbus…

【云原生 Prometheus篇】Prometheus架構詳解與核心組件的應用實例(Exporters、Grafana...)

Prometheus Part1 一、常用的監控系統1.1 簡介1.2 Prometheus和zabbix的區別 二、Prometheus2.1 簡介2.2 Prometheus的主要組件1)Prometheus server2)Exporters3)Alertmanager4)Pushgateway5)Grafana 2.3 Prometheus的…

openGauss學習筆記-130 openGauss 數據庫管理-參數設置-重設參數

文章目錄 openGauss學習筆記-130 openGauss 數據庫管理-參數設置-重設參數130.1 背景信息130.2 GUC參數設置130.3 操作步驟130.4 示例 openGauss學習筆記-130 openGauss 數據庫管理-參數設置-重設參數 130.1 背景信息 openGauss提供了多種修改GUC參數的方法,用戶可…

【網絡】數據鏈路層協議

數據鏈路層協議 一、鏈路層解決的問題二、以太網協議1、局域網技術2、令牌環網(了解)3、以太網通信原理4、 MAC地址5、以太網幀格式6、碰撞避免7、最大傳輸單元MTU 二、ARP協議1、ARP數據的格式2、ARP協議的工作流程3、ARP緩存表4、ARP協議中的一些問題7…

11月23日星期四今日早報簡報微語報早讀

11月23日星期四,農歷十月十一,早報微語早讀。 1、我國5G基站總數達321.5萬個; 2、2023年兩院院士增選結果揭曉,共133人當選; 3、北京低保標準提升至每人每月1395元; 4、上海制定體育發展條例&#xff1a…