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

MySQL索引原理、分類與優(yōu)化實戰(zhàn)深入理解

 更新時間:2026年06月04日 10:54:51   作者:一條泥憨魚  
索引是一種特殊的數(shù)據(jù)結(jié)構(gòu),用于加快數(shù)據(jù)庫表中數(shù)據(jù)的檢索速度,它類似于書籍的目錄,通過建立一個指向數(shù)據(jù)行的快速查找路徑,這篇文章主要介紹了MySQL索引原理、分類與優(yōu)化實戰(zhàn)的相關(guān)資料,需要的朋友可以參考下

前言:

在學(xué)習 MySQL 的過程中,“索引(Index)”一定是最核心、最重要的知識之一。

很多初學(xué)者第一次接觸索引時,會覺得:

  • 概念抽象

  • 原理復(fù)雜

  • B+樹難懂

  • 優(yōu)化不會寫

但實際上:

索引的本質(zhì),就是幫助數(shù)據(jù)庫“快速查找數(shù)據(jù)”。

你可以把它理解成:

書籍的目錄

如果一本書沒有目錄,你想找某一頁內(nèi)容,就只能

一頁一頁翻

但如果有目錄,你就能快速定位

MySQL 索引也是同樣的道理。

這篇文章將從:

  • 什么是索引

  • 為什么需要索引

  • 索引底層原理

  • B+樹結(jié)構(gòu)

  • 索引分類

  • 索引失效

  • SQL優(yōu)化

等多個角度,帶你徹底理解 MySQL 索引。

一、什么是索引?

索引(Index)是數(shù)據(jù)庫中一種:

用于提高查詢效率的數(shù)據(jù)結(jié)構(gòu)。

它的作用:

加快數(shù)據(jù)查詢速度

例如:

我們有一張用戶表:

CREATE TABLE user(
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(20),
    age INT
);

插入10萬條數(shù)據(jù)后:

如果執(zhí)行:

SELECT * FROM user WHERE name='張三';

MySQL 會:

從第一條開始
一條一條找

這種方式叫:

全表掃描

效率非常低。

如果給 name 字段添加索引

CREATE INDEX idx_name ON user(name);

數(shù)據(jù)庫就能快速定位數(shù)據(jù),查詢速度會大幅提升。

二、為什么索引能提高查詢速度?

核心原因:

減少數(shù)據(jù)掃描次數(shù)

沒有索引:

100萬條數(shù)據(jù)
可能掃描100萬次

有索引:

可能只需要掃描幾次

這就像:

沒有目錄的書

你想找:

第500頁內(nèi)容

只能:

從第一頁翻到500頁

有目錄的書

直接:

目錄 → 第500頁

效率差距巨大。

三、索引的底層數(shù)據(jù)結(jié)構(gòu)

很多面試中都會問:

MySQL索引底層是什么?

答案:

B+Tree(B+樹)

四、為什么不用數(shù)組或鏈表?

4.1 數(shù)組的問題

數(shù)組查找快:

支持下標隨機訪問

但是插入數(shù)據(jù)很慢。

例如:

1 2 4 5

插入3:

1 2 3 4 5

后面元素都要移動。

數(shù)據(jù)庫頻繁增刪改,數(shù)組不適合。

4.2 鏈表的問題

鏈表插入快,但查詢慢。

因為:

只能一個一個找

不適合數(shù)據(jù)庫查詢。

4.3 二叉樹的問題

普通二叉樹:

可能退化成鏈表。

例如:

1
 \
  2
   \
    3
     \
      4

查詢效率很差。

五、B+樹是什么?

MySQL 最常用的索引結(jié)構(gòu):

B+Tree

它是一種:

多路平衡搜索樹

特點:

  • 查詢快

  • 層級少

  • 磁盤IO少

  • 非常適合數(shù)據(jù)庫

六、B+樹結(jié)構(gòu)特點

6.1 所有數(shù)據(jù)都在葉子節(jié)點

B+樹中:

真正的數(shù)據(jù):

只存儲在葉子節(jié)點

非葉子節(jié)點只存索引。

6.2 葉子節(jié)點形成鏈表

葉子節(jié)點之間,會形成雙向鏈表。

因此:

范圍查詢效率極高

例如:

SELECT * FROM user WHERE id BETWEEN 100 AND 200;

6.3 樹高度低

B+樹的一個節(jié)點能存很多數(shù)據(jù)。

因此:

樹層級很少

通常:

3~4層

就能存千萬級數(shù)據(jù)。

七、聚簇索引與非聚簇索引

這是 MySQL 高頻面試題。

7.1 聚簇索引(Clustered Index)

InnoDB 中,主鍵索引就是聚簇索引。

特點:

數(shù)據(jù)和索引放在一起

例如:

PRIMARY KEY(id)

葉子節(jié)點,直接存整行數(shù)據(jù)。

7.2 非聚簇索引(二級索引)

普通索引:

CREATE INDEX idx_name ON user(name);

葉子節(jié)點存的是:

主鍵值

查詢時,還要回到主鍵索引查數(shù)據(jù)。

這個過程叫:

回表查詢

八、索引分類

8.1 主鍵索引

創(chuàng)建主鍵時自動生成。

CREATE TABLE student(
    id INT PRIMARY KEY,
    name VARCHAR(20)
);

特點:

  • 唯一

  • 不能為空

8.2 唯一索引

保證字段唯一。

CREATE UNIQUE INDEX idx_phone
ON user(phone);

例如:

手機號不能重復(fù)。

8.3 普通索引

最常見。

CREATE INDEX idx_age
ON user(age);

僅用于提高查詢效率。

8.4 聯(lián)合索引(復(fù)合索引)

多個字段共同組成。

CREATE INDEX idx_name_age
ON user(name,age);

適用于:

WHERE name=? AND age=?

8.5 全文索引

用于:

文本搜索

例如:

FULLTEXT(content)

九、創(chuàng)建索引

9.1 創(chuàng)建普通索引

CREATE INDEX idx_name
ON user(name);

9.2 創(chuàng)建唯一索引

CREATE UNIQUE INDEX idx_email
ON user(email);

9.3 創(chuàng)建聯(lián)合索引

CREATE INDEX idx_name_age
ON user(name,age);

9.4 刪除索引

DROP INDEX idx_name ON user;

十、查看SQL是否使用索引

使用:

EXPLAIN

例如:

EXPLAIN
SELECT * FROM user WHERE name='張三';

十一、EXPLAIN重要字段

11.1 type

SQL性能指標。

常見:

type性能
all全表掃描(最差)
index掃描索引
range范圍查詢
ref普通索引查詢
const主鍵查詢(最好)

11.2 key

使用了哪個索引。

11.3 rows

掃描行數(shù)越少越好。

十二、索引失效場景

很多時候,明明建了索引,但SQL還是很慢。

原因:

索引失效

12.1 對索引列使用函數(shù)

錯誤示例:

SELECT * FROM user
WHERE YEAR(create_time)=2025;

索引失效。

正確:

SELECT * FROM user
WHERE create_time BETWEEN
'2025-01-01'
AND '2025-12-31';

12.2 模糊查詢以%開頭

錯誤:

LIKE '%abc'

索引失效。

正確:

LIKE 'abc%'

12.3 字段類型不一致

例如:

name VARCHAR

但:

WHERE name=123

可能導(dǎo)致隱式轉(zhuǎn)換,索引失效。

12.4 使用or

例如:

WHERE age=18 OR salary=5000

可能索引失效。

12.5 聯(lián)合索引不滿足最左前綴

例如:

(name,age,gender)

SQL:

WHERE age=20

無法使用聯(lián)合索引。

因為:

沒有從最左邊開始

十三、最左前綴原則

聯(lián)合索引最重要的規(guī)則。

例如:

(name,age,gender)

可以使用:

WHERE name=?
WHERE name=? AND age=?
WHERE name=? AND age=? AND gender=?

不能直接:

WHERE age=?

十四、覆蓋索引

什么是覆蓋索引?

即:

查詢的數(shù)據(jù)
剛好都在索引中

不需要回表。

例如:

CREATE INDEX idx_name_age
ON user(name,age);

SQL:

SELECT name,age
FROM user
WHERE name='張三';

由于:

name age 都在索引中

因此:

無需回表

性能更高。

十五、索引不是越多越好

很多初學(xué)者認為索引越多越快,其實這是不對的。

15.1 索引占空間

索引需要額外存儲。

15.2 更新會變慢

執(zhí)行:

INSERT
UPDATE
DELETE

索引也要維護。并且索引越多,維護成本越高。

十六、索引優(yōu)化建議

16.1 高頻查詢字段建索引

例如:

用戶名
手機號
訂單號

16.2 數(shù)據(jù)量小不需要索引

例如:

幾十條數(shù)據(jù)

全表掃描更快。

16.3 區(qū)分度高的字段適合索引

例如:

手機號
身份證號

不適合:

性別

因為:

重復(fù)值太多

16.4 聯(lián)合索引優(yōu)于多個單列索引

推薦:

(name,age)

而不是:

name
age

16.5 盡量使用覆蓋索引

減少回表。

十七、JavaWeb中的索引優(yōu)化場景

17.1 登錄功能

SELECT * FROM user
WHERE username=?;

username 應(yīng)加索引。

17.2 商品搜索

SELECT * FROM product
WHERE category_id=?;

商品分類應(yīng)加索引。

17.3 訂單查詢

SELECT * FROM orders
WHERE user_id=?
ORDER BY create_time DESC;

推薦聯(lián)合索引:

(user_id,create_time)

十八、面試高頻問題

18.1 為什么索引能提高查詢效率?

因為減少了數(shù)據(jù)掃描次數(shù)。

18.2 MySQL索引底層是什么?

B+Tree

18.3 聚簇索引和非聚簇索引區(qū)別?

聚簇索引:

數(shù)據(jù)和索引在一起

非聚簇索引:

索引存主鍵值
需要回表

18.4 什么是回表查詢?

先查普通索引:

再查主鍵索引。

18.5 什么是最左前綴原則?

聯(lián)合索引必須從最左邊字段開始使用。

十九、總結(jié)

索引是 MySQL 性能優(yōu)化的核心。

它的本質(zhì):

幫助數(shù)據(jù)庫快速查找數(shù)據(jù)

重點一定要掌握:

  • B+樹

  • 聚簇索引

  • 聯(lián)合索引

  • 最左前綴

  • 覆蓋索引

  • 索引失效

對于開發(fā)者來說,真正的高性能系統(tǒng):

并不是:

代碼寫得多復(fù)雜

而是:

SQL是否高效
索引是否合理

數(shù)據(jù)庫性能,往往決定整個系統(tǒng)的性能上限。

到此這篇關(guān)于MySQL索引原理、分類與優(yōu)化實戰(zhàn)的文章就介紹到這了,更多相關(guān)MySQL索引原理、分類與優(yōu)化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

龙江县| 菏泽市| 灌阳县| 博罗县| 垦利县| 定安县| 资溪县| 安乡县| 通辽市| 明光市| 永顺县| 徐闻县| 芦山县| 松潘县| 弥勒县| 合作市| 塔城市| 昌吉市| 马关县| 嘉荫县| 陇南市| 遵义县| 田东县| 齐河县| 丰顺县| 澎湖县| 德钦县| 商水县| 辽阳县| 航空| 缙云县| 临城县| 罗甸县| 交口县| 三亚市| 北辰区| 江都市| 荃湾区| 日照市| 靖边县| 井冈山市|