【MySQL基礎篇】:MySQL索引——提升數據庫查詢性能的關鍵

?感謝您閱讀本篇文章,文章內容是個人學習筆記的整理,如果哪里有誤的話還請您指正噢?
? 個人主頁:余輝zmh–CSDN博客
? 文章所屬專欄:MySQL篇–CSDN博客

在這里插入圖片描述

文章目錄

  • 索引
    • 一.MySQL與存儲
    • 二.索引的理解
      • 1.Page頁模式
        • 理解單個Page
        • 理解多個Page
      • 2.頁目錄
        • 單頁情況優化
        • 多頁情況優化
      • 3.B樹 VS B+樹
        • B樹(B-Tree)結構
        • B+樹(B+Tree)結構
      • 4.聚簇索引 VS 非聚簇索引
        • 聚簇索引
        • 非聚簇索引
    • 三.索引的操作
      • 創建索引
      • 查詢索引
      • 刪除索引
      • 查詢索引
      • 刪除索引

索引

一.MySQL與存儲

MySQL給用戶提供存儲服務,而存儲的都是數據,數據在磁盤這個外設當中;但是磁盤是計算機中的一個機械設備,相比于其他的電子元件,磁盤效率是比較低的,再加上IO本身的特征,可以知道,如何提交IO效率,是MySQL的一個重要話題(接下來的內容全部都是圍繞這個話題來展開)

1.MySQL,系統和磁盤三者之間的IO交互

現代操作系統的內存被劃分為兩個主要區域:

  • 用戶空間:應用程序運行的地方,MySQL服務器進程在此空間運行

  • 內核空間:操作系統內核運行的地方,負責系統級操作

首先MySQL作為一個應用程序,運行在操作系統的用戶空間中,他并沒有直接訪問硬件設備的權限,這是現代操作系統的一個重要安全特性——內存保護機制

MySQL需要讀取或寫入數據時,不能直接訪問磁盤,必須通過操作系統作為中介,由操作系統去訪問磁盤,因此三者之間的IO交互過程就是:MySQL——>系統——>磁盤

IO交互流程詳解:

  1. 請求發起階段

MySQL需要讀取磁盤數據時,首先在用戶空間發起請求,通過系統調用進入內核空間;

  1. 權限切換
  • 用戶態 → 內核態:系統調用觸發CPU模式切換;

  • 權限提升:獲得直接訪問硬件和內核資源的權限;

  1. 內核處理階段

操作系統內核接收到請求后:

  • 檢查文件系統緩存;

  • 如果緩存未命中,向磁盤控制器發送I/O請求;

  • 將數據從磁盤讀取到內核緩沖區(4KB頁大小);

  1. 數據傳遞階段
  • 內核緩沖區 → MySQL緩沖區:將4KB的數據拷貝到用戶空間的MySQL緩沖區;

  • 數據整合:MySQL可能將多個4KB頁組合成16KB的數據庫頁;

  1. 返回用戶態

系統調用完成,CPU重新切換回用戶態,MySQL繼續在用戶空間處理數據;

關鍵理解點:

空間隔離

  • MySQL服務器和操作系統都在內存中運行;

  • 但工作在不同的內存空間:用戶空間 vs 內核空間;

  • 這種隔離確保了系統安全性和穩定性;

雙重IO概念

  • 系統與磁盤的IO交互:磁盤數據拷貝到內核緩沖區(4KB);
  • MySQL與系統的IO交互:內核緩沖區數據拷貝到MySQL緩沖區(16KB);

2.為什么磁盤的最小讀寫單位是512字節的扇區,但系統卻選擇4KB作為IO操作的基本單位,這是因為

  • 如果操作系統直接使用硬件磁盤提供的數據大小進行交互,那么系統的IO代碼,就和硬件強相關,就好比,一旦硬件發生變化,系統也必須跟著變化;
  • 除此之外,單次IO交互只有512字節,還是太小了;IO單位越小,意味著讀取同樣的數據內容,需要進行多次磁盤訪問,從會帶來IO效率上的降低;
  • 并且之前學習的文件系統,就是在磁盤的基本結構下建立的,而文件系統的基本讀取單位就不是扇區512字節,而是數據塊4KB

因此,系統和磁盤進行IO交互時,是以數據塊4KB為單位的。

3.為什么MySQL與系統這里IO操作的基本單位又是16KB,這是因為:

每次系統調用都涉及:

  • 上下文切換:用戶態?內核態的CPU模式切換;

  • 寄存器保存/恢復:需要保存當前進程狀態;

  • 內存拷貝:數據在用戶空間和內核空間之間的傳輸;

  • 調度開銷:可能涉及進程調度;

MySQL作為一款應用軟件,可以想象成一種特殊的文件系統,他有著更高的IO場景,所以,為了提高基本的IO效率,MySQL的優化策略采用了批量處理原則:

  • 減少系統調用次數:通過增加單次傳輸數據量來減少調用頻率;

  • 4KB → 16KB:將多個系統頁合并成一個數據庫頁;

  • 預讀機制:一次性讀取可能需要的連續數據;

MySQL直接和系統進行IO交互的基本單位是16KB(后面統一使用InnoDB存儲引擎講解),而不是系統的4KB;這也相當于MySQL間接和磁盤進行數據交互的基本單位也是16KB;這個16KB基本數據單元,在MySQL這里叫作page,也可以叫做(注意不是系統的4KBpage,兩者有區別的)。

這樣的優化策略,可以使原本的4次系統調用優化后變成只需要1-2次系統調用,大大減少了系統調用的開銷;

此外還能提高數據吞吐量:

  • 更大的數據塊:每次傳輸更多有用數據;

  • 更好的緩存命中率:16KB頁可能包含更多相關數據;

  • 減少碎片化:減少小數據塊的隨機訪問;

4.最后總結

  • MySQL中的數據文件,是以page(16KB頁)為單位保存在磁盤中的;
  • MySQL中表數據的增刪查改(CURD操作),都需要通過計算,找到對應的插入位置,或者找到對應的修改或者查詢的數據;
  • 而只要涉及到計算,就需要CPU的參與,需要先將數據從磁盤加載到內存中;
  • MySQL服務器在內存中運行的時候,在服務器內部就申請了一個Buffer Poll的大內存空間,來進行各種緩存。其實就是一個很大的用戶級緩沖區,來和磁盤數據進行IO交互;
  • 所以在特定的時間內,數據一定是在磁盤中有,內存中也有。后續操作完內存數據后,再以特定的刷新策略,將內存上的數據刷新到磁盤中,保證數據被修改 。而這時,就涉及到磁盤和內存的數據交互,也就是IO了,而此時IO的基本單位就是page;
  • 為了更高的IO效率,就一定要盡可能地減少IO的次數;

二.索引的理解

1.Page頁模式

建立測試表

mysql> CREATE TABLE users(-> id int PRIMARY KEY,-> age int NOT NULL,-> name varchar(30) NOT NULL-> );
Query OK, 0 rows affected (0.42 sec)mysql> DESC users;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int         | NO   | PRI | NULL    |       |
| age   | int         | NO   |     | NULL    |       |
| name  | varchar(30) | NO   |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.02 sec)

插入多條記錄

mysql> INSERT INTO users values-> (5, 20, '張三'),-> (3, 18, '李四'),-> (1, 19, '王五'),-> (2, 21, '趙六'),-> (4, 19, '陳七');
Query OK, 5 rows affected (0.01 sec)
Records: 5  Duplicates: 0  Warnings: 0

查看插入結果

mysql> SELECT * FROM users;
+----+-----+--------+
| id | age | name   |
+----+-----+--------+
|  1 |  19 | 王五   |
|  2 |  21 | 趙六   |
|  3 |  18 | 李四   |
|  4 |  19 | 陳七   |
|  5 |  20 | 張三   |
+----+-----+--------+
5 rows in set (0.00 sec)

根據上面的結果,可以發現雖然插入時故意設置成無序的,但是查看結果時,顯示的確實有序的結果,這就是我們想要看到的一個現象。

那為什么變成有序的呢?這又是誰干的?這樣排序又有什么好處呢?

首先數據按照id字段自動排序顯示,這是因為id字段被定義為 PRIMARY KEY(主鍵),MySQL會自動為主鍵創建聚集索引;

聚集索引特性:在InnoDB存儲引擎中,表數據實際上是按照主鍵的順序物理存儲的;

所以當查看數據時,MySQL優化器會選擇使用主鍵索引來掃描數據,自然就按照主鍵順序返回結果;

因此變成有序是因為聚集索引的特性以及查詢優化,這個工作當然就是由MySQL數據庫存儲引擎自動完成的了。

至于這樣排序有什么好處,在回答這個問題之前先來回到另一個問題:

為什么MySQL與磁盤的IO交互采用Page模式,而不是用多少,加載多少的逐條加載模式?

如果是逐條加載模式

查找id=1 → 加載1次
查找id=2 → 加載2次(需要先加載id=1)
查找id=5 → 加載5次(需要加載id=1,2,3,4,5)

而Page模式

查找id=1 → 加載1個page(包含id=1,2,3,4,5)
查找id=2 → 從內存緩沖區獲取(無需IO)
查找id=5 → 從內存緩沖區獲取(無需IO)

在前面已經提到過:為了更高的IO效率,就需要減少IO交互的次數;

顯然采用逐條加載的方式,隨著數據越來越多,當要查詢較大的id值時,所需要的加載次數就會越來越大;而Page方式可以一次性加載多個數據(16KB大小),加載后保存在MySQL緩沖區中,即使部分數據本次用不到,但是可能在之后的查詢中就會用到,這時候就不需要重新和磁盤進行IO交互,而是直接從緩沖區中讀取即可,這樣就大大的減少了IO交互的次數;所以采用Page方式進行IO交互,而不是逐條加載的方式。

明白了這一點,再來看為什么需要進行排序?

排序的重要性:

  • 局部性原理:相同的數據很可能被一起訪問;
  • 預讀優化:MySQL可以預測性的加載后續頁面;
  • 緩存命中率:有序數據更容易保持在內存中;
  • 減少磁盤尋道:有序數據在磁盤中的扇區地址也是連續的,順序訪問減少磁頭移動
理解單個Page

一個表中如果有大量的數據,就需要大量的page進行存儲,也就是說內存中會存在大量的page;因此系統需要對這些page進行管理,管理方式就是先描述再組織,先描述:將page抽象成一個個的結構體,再組織:用數據結構將每個page組織起來;并且數據庫表本質上就是文件,所以一個獨立的文件是由一個或多個page組成的。

在這里插入圖片描述

不同的Page,在MySQL中,都是16KB,使用prevnext構成雙向鏈表;因為有主鍵得存在,MySQL會默認按照主鍵給我們的數據進行排序,從上面的Page內數據記錄可以看出,數據是有序且彼此關聯的;

所以前面提到得存儲數據時要進行排序的好處,除了前面提到的幾點之外,還有一點就是:

Page內部存放數據的模塊,本質上也是一個鏈表結構,鏈表的特點也就是增刪查改,查詢修改慢,所以優化查詢的效率是必須的;正是因為有序,在查找的時候,從頭到后都是有效的查找,沒有任何一個查找是浪費的,而且,如果運氣好,是可以提前結束查找過程的

理解多個Page

在上面的頁模式中,只有一個功能,就是在查詢某條數據的時候直接將一整頁的數據加載到內存中,以減少硬盤IO次數,從而提高性能。但是,我們也可以看到,現在的頁模式內部,實際上是采用了鏈表的結構,前一條數據指向后一條數據,本質上還是通過數據的逐條比較來取出特定的數據;

那假如有1千萬條數據,就一定需要多個Page來保存1千萬條數據,多個Page彼此使用雙鏈表鏈接起來,而且每個Page內部的數據也是基于鏈表的;那么,查找特定一條記錄,也一定是線性查找;這效率就會大大降低。

在這里插入圖片描述

兩次鏈表遍歷

  • 頁間遍歷:從第一個Page開始,逐個遍歷Page鏈表,直到找到目標Page;

  • 頁內遍歷:在目標Page內部,從第一條記錄開始,逐個遍歷記錄鏈表,直到找到目標數據;

為了解決數據量過大時,兩次鏈表遍歷帶來的效率低下問題,就需要引入一個新的概念頁目錄來解決;

2.頁目錄

先來理解一下什么是頁目錄?

想象一下你有一本很厚的書,比如《哈利波特》全集;這本書有幾千頁,如果你想快速找到某個特定的章節或內容,你會怎么做?

方法1:從頭開始一頁頁翻

  • 這就像沒有索引的數據庫表,要找到某條記錄需要全表掃描;

方法2:使用目錄

  • 書的前面有目錄,告訴你每個章節在第幾頁;

  • 這就是頁目錄的作用!

單頁情況優化

頁內目錄管理

  • 一個數據頁內部包含頁目錄數據記錄

  • 每個頁目錄項由:鍵值+指針構成;

  • 這里的指針指向的是某行數據記錄的位置,也就是說頁內目錄管理的級別是

在這里插入圖片描述

在一個Page內部,引入頁目錄之后,當要查找id=4的記錄,之前必須先行遍歷4次,才能拿到結果,現在直接通過頁目錄2[3]就可以定位到新的起始位置,然后開始線性遍歷,不用再從最起始位置開始遍歷,大大提高了效率;

這時候再來看前面的那個問題,為什么存儲數據時要進行排序?這里的頁目錄不就很好的體現出來優勢了。

單個Page內部的頁目錄優化

  • 原來:從Page內第一條記錄開始,逐個遍歷記錄鏈表;

  • 現在:先在頁目錄中查找,找到最接近目標記錄的位置,然后從該位置開始遍歷;

  • 效果:大大減少了Page內部的遍歷次數;

多頁情況優化

接下來就是解決數據頁之間的鏈表遍歷所帶來的效率問題,根據數據頁內部的解決方式,也可以給每個數據頁也帶上目錄:

頁間目錄管理

  • 一個目錄頁內部只包含頁目錄,不包含數據記錄
  • 每個頁目錄項由:鍵值+指針構成;
  • 這里的指針指向的是某頁的位置,也就是說頁間目錄管理的級別是

在這里插入圖片描述

存在一個目錄頁來管理頁目錄,目錄頁中的鍵值指的是那一頁中最小的數據,通過鍵值數據的比較,找到目標頁,再根據指針到目標頁中查找目標數據;

目錄頁的本質也是頁,只不過數據頁中的數據是表中的行數據記錄,而目錄頁中的數據其實就是每個數據頁的指針

但是,對于數據記錄量非常大的表,可能會出現頁目錄之間的鏈表也逐漸變長的情況,導致目錄頁之間的鏈表遍歷降低效率,這里就不用擔心了,根據頁目錄的思路,我們可以給每個目錄頁也添加頁目錄,形成多級索引結構,比如說一級頁目錄,二級頁目錄等等,逐步形成一個龐大的B+樹;

在這里插入圖片描述

這正是MySQL B+樹索引的核心設計思想

3.B樹 VS B+樹

B樹(B-Tree)結構

1.B樹的基本概念

B樹是一種自平衡的多路搜索樹,專門為磁盤存儲設計;

B樹的特點

B樹節點結構示例(m階B樹):
┌─────┬─────┬─────┬─────┬─────┐
│ P0  │ K1  │ P1  │ K2  │ P2  │
└─────┴─────┴─────┴─────┴─────┘其中:
- Ki:關鍵字(索引值)
- Pi:指向子節點的指針
- 每個節點最多有m個子節點
- 每個節點最少有?m/2?個子節點(根節點除外)

2.B樹的性質

  • 所有葉子節點都在同一層;
  • 葉子節點和非葉子節點都存儲索引和數據;
  • 節點內關鍵字按升序排列;
  • 滿足平衡性要求;

3.B樹查找過程

假設查找關鍵字K:

  1. 從根節點開始;
  2. 在當前節點中查找K;
  3. 如果找到,直接返回結果;
  4. 如果沒找到,根據K的大小選擇對應的子節點指針;
  5. 重復2,3,4步驟,直到找到或達到葉子節點;
B+樹(B+Tree)結構

1.B+樹的基本概念

B+樹是B樹的變種,是MySQL InnoDB存儲引擎使用的主要索引結構;

2.B+樹的結構特點

B+樹結構示例:根節點(非葉子)┌─────────┬─────────┬─────────┐│   102030    │└────┬────┴────┬────┴────┬────┘│         │         │┌────────┴──┐ ┌────┴────┐ ┌──┴────────┐│  58  │ │ 1518 │ │ 2535  │  非葉子節點└──┬───┴─┬──┘ └─┬──┴─┬──┘ └─┬──┴──┬──┘│     │      │    │      │     │葉子節點層(存儲實際數據):┌───┬───┐ ┌───┬───┐ ┌───┬───┐ ┌───┬───┐ ┌───┬───┐ ┌───┬───┐│ 34 │→│ 56 │→│ 89 │→│1516 │→│1819 │→│2526 │└───┴───┘ └───┴───┘ └───┴───┘ └───┴───┘ └───┴───┘ └───┴───┘↑_______________________________________|(雙向鏈表)
  • 節點結構差異
-- 非葉子節點(只存儲索引)
┌─────┬─────┬─────┬─────┬─────┐
│ P0  │ K1  │ P1  │ K2  │ P2  │  -- 只有索引值和指針
└─────┴─────┴─────┴─────┴─────┘-- 葉子節點(存儲完整數據)
┌─────┬─────┬─────┬─────┬─────┬─────┐
│ K1  │ Data│ K2  │ Data...Next-- 索引值+完整數據+鏈表指針
└─────┴─────┴─────┴─────┴─────┴─────┘
  • 葉子節點鏈表結構

所有葉子節點通過雙向鏈表連接,支持高效的范圍查詢;

3.B樹 VS B+樹

  • 數據存儲位置

B樹:

  • 非葉子節點和葉子節點都存儲數據;
  • 數據分散在整個樹中;

B+樹:

  • 只有葉子節點存儲完整數據;
  • 非葉子節點只存儲索引值;
  • 查詢性能對比

等值查詢

  • B樹:可能在任何層找到數據,查詢路徑不固定;
  • B+樹:必須到葉子節點,查詢路徑固定,IO次數穩定;

范圍查詢

  • B樹:需要進行中序遍歷,效率較低;

  • B+樹:利用葉子節點鏈表,效率極高;

  • 存儲空間利用率

B+樹優勢:

  • 非葉子節點不存儲數據,可以存儲更多索引項;
  • 相同的頁面大小可以有更高的扇出比(fanout);
  • 樹的高度更低,查詢IO次數更少;

計算示例:
假設頁面大小16KB,索引項8字節,數據100字節:

  • B樹:每個節點約存儲 16KB/(8+100)B ≈ 151個項;
  • B+樹非葉子:每個節點約存儲 16KB/8B = 2048個項;
  • 磁盤IO效率

B+樹在磁盤IO方面的優勢:

  1. 更低的樹高度 → 更少的磁盤訪問;
  2. 順序訪問友好 → 利用磁盤預讀;
  3. 更好的緩存局部性;

這就是為什么MySQL InnoDB存儲引擎選擇B+樹作為索引結構的核心原因,它完美適配了數據庫系統對高效查詢、范圍搜索和磁盤IO優化的需求。

4.聚簇索引 VS 非聚簇索引

聚簇索引

1.基本概念

聚簇索引就是數據和索引存儲在一起的索引,索引的葉子節點直接存儲完整的行數據;

2.特點

聚簇索引結構:根節點/   |   \內部節點  內部節點  內部節點/  |  \   /  |  \   /  |  \[葉子][葉子][葉子][葉子][葉子][葉子]↓     ↓     ↓     ↓     ↓     ↓
完整行數據 完整行數據 完整行數據 完整行數據 完整行數據 完整行數據
  • 一個表中只能有一個聚簇索引(通常是主鍵);
  • 數據按照索引順序物理存儲;
  • 查詢時通過聚簇索引找到葉子節點,直接返回整行數據;
非聚簇索引

1.基本概念

非聚簇索引是索引和數據分開存儲的,索引葉子節點存儲的是主鍵值。

2.特點

非聚簇索引結構:根節點/   |   \內部節點  內部節點  內部節點/  |  \   /  |  \   /  |  \[葉子][葉子][葉子][葉子][葉子][葉子]↓     ↓     ↓     ↓     ↓     ↓主鍵ID  主鍵ID  主鍵ID  主鍵ID  主鍵ID  主鍵ID↓     ↓     ↓     ↓     ↓     ↓通過主鍵再次查找聚簇索引獲取完整數據
  • 一個表可以有多個非聚簇索引;
  • 需要回表操作(先查索引,再查數據);
  • 查詢時通過非聚簇索引找到葉子節點,獲取該記錄對應的主鍵ID值;
  • 再通過主鍵id在聚簇索引中查找完整行數據;

簡單總結

聚簇索引:數據和索引在一起,查詢快但只能有一個,適用于主鍵查詢,范圍查詢,排序操作等場景;一次查找,直接獲取整行數據

非聚簇索引:索引指向數據位置,需要回表但可以有多個,適用于多條件查詢,輔助查詢條件等場景;兩次查找,先獲取主鍵,再回表通過主鍵獲取整行數據

MySQL InnoDB中:

  • 主鍵 = 聚簇索引

  • 其他索引 = 非聚簇索引

三.索引的操作

創建索引

創建主鍵索引

  • 第一種方式
-- 在創建表時,直接在字段名后指定主鍵索引
mysql> CREATE TABLE user1(-> id int PRIMARY KEY,-> name varchar(30) NOT NULL,-> age int NOT NULL-> );
Query OK, 0 rows affected (0.07 sec)
  • 第二種方式
-- 在創建表的最后,指定某列或某幾列為主鍵索引
mysql> CREATE TABLE user2(-> id int,-> name varchar(30) NOT NULL,-> age int NOT NULL,-> PRIMARY KEY(id)-> );
Query OK, 0 rows affected (0.06 sec)
  • 第三種方式
mysql> CREATE TABLE user3(-> id int,-> name varchar(30) NOT NULL,-> age int NOT NULL-> );
Query OK, 0 rows affected (0.05 sec)-- 創建表以后添加主鍵索引
mysql> ALTER TABLE user3 add PRIMARY KEY(id);
Query OK, 0 rows affected (0.11 sec)
Records: 0  Duplicates: 0  Warnings: 0

主鍵索引的特點:

  • 一個表中,最多有一個主鍵索引,當然可以是復合主鍵;
  • 主鍵索引的效率高(主鍵不可重復)
  • 創建主鍵索引的列,它的值不能為NULL,且不能重復;
  • 主鍵索引的列基本上是int;

唯一鍵索引的創建

  • 第一種方式
-- 在表定義時,在某列后直接指定unique唯一屬性。
mysql> CREATE TABLE user4(-> id int UNIQUE-> ,name varchar(30) NOT NULL,-> age int NOT NULL-> );
Query OK, 0 rows affected (0.07 sec)
  • 第二種方式
-- 創建表時,在表的后面指定某列或某幾列為unique
mysql> CREATE TABLE user5(-> id int,-> name varchar(30) NOT NULL,-> age int NOT NULL,-> UNIQUE(id)-> );
Query OK, 0 rows affected (0.05 sec)
  • 第三種方式
mysql> CREATE TABLE user6(-> id int,-> name varchar(30) NOT NULL,-> age int NOT NULL-> );
Query OK, 0 rows affected (0.05 sec)
-- 創建表以后添加唯一鍵索引mysql> ALTER TABLE user6 add UNIQUE(id);
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0

唯一鍵索引的特點:

  • 一個表中,可以有多個唯一索引;
  • 查詢效率高;
  • 如果在某一列建立唯一索引,必須保證這列不能有重復數據;
  • 如果一個唯一索引上指定not null,等價于主鍵索引;

普通索引的創建

  • 第一種方式
-- 在表的定義最后,指定某列為索引
mysql> CREATE TABLE user7(-> id int,-> name varchar(30) NOT NULL,-> age int NOT NULL,-> index(id)-> );
Query OK, 0 rows affected (0.06 sec)
  • 第二種方式
mysql> CREATE TABLE user8(-> id int,-> name varchar(30) NOT NULL,-> age int NOT NULL-> );
Query OK, 0 rows affected (0.06 sec)
-- 創建表以后添加普通索引
mysql> ALTER TABLE user8 ADD INDEX(id);
Query OK, 0 rows affected (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 0
  • 第三種方式
CREATE TABLE user9(id INT,name VARCHAR(30) NOT NULL,age INT NOT NULL);-- 指定索引名CREATE INDEX idx_id ON user9(id);-- 或ALTER TABLE user9 ADD INDEX idx_id(id);

普通索引的特點:

  • 一個表中可以有多個普通索引,普通索引在實際開發中用的比較多;
  • 如果某列需要創建索引,但是該列有重復的值,那么我們就應該使用普通索引;

查詢索引

  • 第一種方式
SHOW KEYS FROM 表名
  • 第二種方式
SHOW INDEX FROM 表名
  • 第三種方式
DESC 表名

刪除索引

  • 第一種方式
-- 刪除主鍵索引
ALTER TABLE 表名 DROP PRIMARY KEY;
  • 第二種方式
-- 其他索引的刪除
ALTER TABLE 表名 DROP INDEX 索引名
  • 第三種方式
DROP INDEX 索引名 ON 表名

ec)
Records: 0 Duplicates: 0 Warnings: 0


- 第三種方式```sql  
CREATE TABLE user9(id INT,name VARCHAR(30) NOT NULL,age INT NOT NULL);-- 指定索引名CREATE INDEX idx_id ON user9(id);-- 或ALTER TABLE user9 ADD INDEX idx_id(id);

普通索引的特點:

  • 一個表中可以有多個普通索引,普通索引在實際開發中用的比較多;
  • 如果某列需要創建索引,但是該列有重復的值,那么我們就應該使用普通索引;

查詢索引

  • 第一種方式
SHOW KEYS FROM 表名
  • 第二種方式
SHOW INDEX FROM 表名
  • 第三種方式
DESC 表名

刪除索引

  • 第一種方式
-- 刪除主鍵索引
ALTER TABLE 表名 DROP PRIMARY KEY;
  • 第二種方式
-- 其他索引的刪除
ALTER TABLE 表名 DROP INDEX 索引名
  • 第三種方式
DROP INDEX 索引名 ON 表名

以上就是關于MySQL索引結構的講解,如果哪里有錯的話,可以在評論區指正,也歡迎大家一起討論學習,如果對你的學習有幫助的話,點點贊關注支持一下吧!!!

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

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

相關文章

TD-IDF的一些應用

TF-IDF(詞頻 - 逆文檔頻率)作為經典的文本特征提取算法,在自然語言處理(NLP)領域應用廣泛。它能將文本轉化為可量化的數值特征,為后續的數據分析和建模提供基礎。本文結合實際場景,介紹如何用 P…

Redis 緩存問題詳解及解決方案

一、緩存擊穿 (Cache Breakdown) 原理: 某個熱點 Key 突然過期,同時大量并發請求該 Key,導致請求直接穿透緩存擊穿到數據庫。 解決方案: 互斥鎖 (Mutex Lock) 當緩存失效時,僅允許一個線程重建緩存,其他線程…

一周一個數據結構 第一周 --- 順序表(下)

文章目錄一、ArrayList的構造二、ArrayList常見操作三、ArrayList的遍歷四、ArrayList練習1.【小練習】2.楊輝三角3.簡單的洗牌算法五、ArrayList小結在上一章節中,我們通過代碼示例以及畫圖的方式詳細了解了順序表,并模擬實現了它。那么,是不…

OpenCV的關于圖片的一些運用

一、讀取圖片通過cv2庫中的imread()方法讀取圖片代碼:import cv2 a cv2.imread(1.png) cv2.imshow(tu,a) b cv2.waitKey(4000) # 圖片執行時間 cv2.destroyAllWindows() # 關閉所有端口 print("圖像形狀(shape):",a.shape) print…

【數據結構——并查集】

引入 并查集(Disjoint Set Union,DSU)是一種用于管理元素分組的數據結構。 合并(Union):將兩個不相交的集合合并為一個集合。 查找(Find):確定某個元素屬于哪個集合&…

在 Vue 中使用 ReconnectingWebSocket實現即時通訊聊天客服功能

在 Vue 中使用 ReconnectingWebSocketReconnectingWebSocket 是一個自動重連的 WebSocket 實現,非常適合在 Vue 項目中使用。下面是如何在 Vue 中集成和使用它的方法:搜索 "程序員老狼"安裝 ReconnectingWebSocket首先,你需要安裝…

智能體革命:網絡安全人的角色重塑與突圍指南

AI賦能千行百業的趨勢不可逆轉,當AI學會滲透測試,安全工程師的出路在哪里? 2025年8月7日,OpenAI正式發布GPT-5的消息刷屏科技圈。這個達到博士生水平的“統一”人工智能模型,將AI幻覺率降低60%,成本下降45%…

用于水T1值和脂肪分數量化的上半身自由呼吸磁共振指紋成像|文獻速遞-醫學影像算法文獻分享

Title題目Upper-body free-breathing Magnetic Resonance Fingerprinting applied tothe quantification of water T1 and fat fraction用于水T1值和脂肪分數量化的上半身自由呼吸磁共振指紋成像 01文獻速遞介紹磁共振指紋成像(MRF)是十年前推出的一種高…

Apache RocketMQ:消息可靠性、順序性與冪等處理的全面實踐

Apache RocketMQ 是一個高性能、高可靠的分布式消息中間件,廣泛應用于異步通信、事件驅動架構和分布式系統中。本文深入探討 RocketMQ 的消息可靠性、順序性和冪等處理機制,結合 Redisson 分布式鎖實現冪等消費,提供詳細的代碼示例和實踐建議…

無服務器日志分析由 Elasticsearch 提供支持,推出新的低價層

作者:來自 Elastic Log Analytics Elastic Observability Logs Essentials 在 Elastic Cloud Serverless 上提供成本效益高、無麻煩的日志分析。 SREs 可以攝取、搜索、豐富、分析、存儲和處理日志,而無需管理部署的運營開銷。[](https://www.elastic.co…

(Arxiv-2025)Phantom-Data:邁向通用的主體一致性視頻生成數據集

Phantom-Data:邁向通用的主體一致性視頻生成數據集 paper是字節發布在Arxiv2025的工作 paper title:Phantom-Data: Towards a General Subject-Consistent Video Generation Dataset Code:鏈接 Abstract 近年來,主體到視頻&#…

如何解決pip安裝報錯ModuleNotFoundError: No module named ‘mlflow’問題

【Python系列Bug修復PyCharm控制臺pip install報錯】如何解決pip安裝報錯ModuleNotFoundError: No module named ‘mlflow’問題 摘要 在Python開發中,pip install 報錯是一種常見問題,尤其是在使用集成開發環境(IDE)如PyCharm時…

2020/12 JLPT聽力原文 問題一 3番

3番:會社で女の人と男の人が話しています。女の人は倉庫に入るとき、どの順番で入口のボタンを押さなければなりませんか。 女:すみません。地下の倉庫に行って、資料を取ってきたいんですが、入口の開け方がわからなくて… 男:ああ、最近、管…

C#/.NET/.NET Core技術前沿周刊 | 第 49 期(2025年8.1-8.10)

前言 C#/.NET/.NET Core技術前沿周刊,你的每周技術指南針!記錄、追蹤C#/.NET/.NET Core領域、生態的每周最新、最實用、最有價值的技術文章、社區動態、優質項目和學習資源等。讓你時刻站在技術前沿,助力技術成長與視野拓寬。 歡迎投稿、推薦…

基于強化學習的目標跟蹤 研究初探

強化學習 目標跟蹤Visual tracking by means of deep reinforcement learning and an expert demonstratorYOLO 檢測下基于 ETC-DDPG 算法的無人機視覺跟蹤基于特征與深度強化學習方法的機器人視覺伺服技術研究高性能可拓展視頻目標跟蹤算法研究基于目標運動與外觀特征的多目標…

排序與查找,簡略版

數組的排序 排序的基本介紹 排序是將一組數據,按照一定順序進行排列的過程 排序的分類: 內部排序: 一次性適用數據量小的情況 將需要處理的數據都加載到內部存儲器中進行排序。包括交換式排序,選擇式排序,插入式排序 外…

打靶日常-XSS(反射型和存儲型)

目錄 小皮: 1. 2.這里需要登錄,我們之前爆破出賬號密碼在這里就可以用?編輯 登錄之后:?編輯 使用工具: 先輸入正確字符進行測試:aaa 進行測試: 3.換種控制臺顯示 結果:(使用f12大法) DVWA: 反射型XSS: 低: ?編輯 中:大小寫繞過: ?編輯 也可以雙寫繞過: ?編…

二叉搜索樹深度解析:從原理實現到算法應用----《Hello C++ Wrold!》(18)--(C/C++)

文章目錄前言二叉搜索樹(二叉排序樹或二叉查找樹)二叉搜索樹的模擬實現二叉搜索樹和有序數組二分查找的比較兩個搜索模型作業部分前言 二叉搜索樹(Binary Search Tree,簡稱 BST)作為一種重要的樹形數據結構&#xff0…

牛客.空調遙控二分查找牛客.kotori和氣球(數學問題)力扣.二叉樹的最大路徑和牛客.主持人調度(二)

目錄 牛客.空調遙控 二分查找 牛客.kotori和氣球(數學問題) 力扣.二叉樹的最大路徑和 牛客.主持人調度(二) 牛客.空調遙控 枚舉n個空調之后,使數組有序,左右下標,用二分查找,然后一個求 長度就好 二分查找 /二分理…

《嵌入式Linux應用編程(二):標準IO高級操作與文件流定位實戰》

今日學習內容1. 行輸入函數安全實踐(1) fgets vs gets函數安全特性換行符處理緩沖區保護fgets指定讀取長度(size-1)保留\n并添加\0安全(防溢出)gets無長度限制將\n替換為\0危險2. Linux標準文件流文件流符號設備 標準輸入stdin鍵盤…