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

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

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

前言:

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

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

  • 概念抽象

  • 原理復(fù)雜

  • B+樹(shù)難懂

  • 優(yōu)化不會(huì)寫(xiě)

但實(shí)際上:

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

你可以把它理解成:

書(shū)籍的目錄

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

一頁(yè)一頁(yè)翻

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

MySQL 索引也是同樣的道理。

這篇文章將從:

  • 什么是索引

  • 為什么需要索引

  • 索引底層原理

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

  • 索引分類

  • 索引失效

  • SQL優(yōu)化

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

一、什么是索引?

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

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

它的作用:

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

例如:

我們有一張用戶表:

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

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

如果執(zhí)行:

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

MySQL 會(huì):

從第一條開(kāi)始
一條一條找

這種方式叫:

全表掃描

效率非常低。

如果給 name 字段添加索引

CREATE INDEX idx_name ON user(name);

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

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

核心原因:

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

沒(méi)有索引:

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

有索引:

可能只需要掃描幾次

這就像:

沒(méi)有目錄的書(shū)

你想找:

第500頁(yè)內(nèi)容

只能:

從第一頁(yè)翻到500頁(yè)

有目錄的書(shū)

直接:

目錄 → 第500頁(yè)

效率差距巨大。

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

很多面試中都會(huì)問(wèn):

MySQL索引底層是什么?

答案:

B+Tree(B+樹(shù))

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

4.1 數(shù)組的問(wèn)題

數(shù)組查找快:

支持下標(biāo)隨機(jī)訪問(wèn)

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

例如:

1 2 4 5

插入3:

1 2 3 4 5

后面元素都要移動(dòng)。

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

4.2 鏈表的問(wèn)題

鏈表插入快,但查詢慢。

因?yàn)椋?/p>

只能一個(gè)一個(gè)找

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

4.3 二叉樹(shù)的問(wèn)題

普通二叉樹(shù):

可能退化成鏈表。

例如:

1
 \
  2
   \
    3
     \
      4

查詢效率很差。

五、B+樹(shù)是什么?

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

B+Tree

它是一種:

多路平衡搜索樹(shù)

特點(diǎn):

  • 查詢快

  • 層級(jí)少

  • 磁盤IO少

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

六、B+樹(shù)結(jié)構(gòu)特點(diǎn)

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

B+樹(shù)中:

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

只存儲(chǔ)在葉子節(jié)點(diǎn)

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

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

葉子節(jié)點(diǎn)之間,會(huì)形成雙向鏈表。

因此:

范圍查詢效率極高

例如:

SELECT * FROM user WHERE id BETWEEN 100 AND 200;

6.3 樹(shù)高度低

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

因此:

樹(shù)層級(jí)很少

通常:

3~4層

就能存千萬(wàn)級(jí)數(shù)據(jù)。

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

這是 MySQL 高頻面試題。

7.1 聚簇索引(Clustered Index)

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

特點(diǎn):

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

例如:

PRIMARY KEY(id)

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

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

普通索引:

CREATE INDEX idx_name ON user(name);

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

主鍵值

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

這個(gè)過(guò)程叫:

回表查詢

八、索引分類

8.1 主鍵索引

創(chuàng)建主鍵時(shí)自動(dòng)生成。

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

特點(diǎn):

  • 唯一

  • 不能為空

8.2 唯一索引

保證字段唯一。

CREATE UNIQUE INDEX idx_phone
ON user(phone);

例如:

手機(jī)號(hào)不能重復(fù)。

8.3 普通索引

最常見(jiàn)。

CREATE INDEX idx_age
ON user(age);

僅用于提高查詢效率。

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

多個(gè)字段共同組成。

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性能指標(biāo)。

常見(jiàn):

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

11.2 key

使用了哪個(gè)索引。

11.3 rows

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

十二、索引失效場(chǎng)景

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

原因:

索引失效

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

錯(cuò)誤示例:

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

索引失效。

正確:

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

12.2 模糊查詢以%開(kāi)頭

錯(cuò)誤:

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

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

因?yàn)椋?/p>

沒(méi)有從最左邊開(kāi)始

十三、最左前綴原則

聯(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 都在索引中

因此:

無(wú)需回表

性能更高。

十五、索引不是越多越好

很多初學(xué)者認(rèn)為索引越多越快,其實(shí)這是不對(duì)的。

15.1 索引占空間

索引需要額外存儲(chǔ)。

15.2 更新會(huì)變慢

執(zhí)行:

INSERT
UPDATE
DELETE

索引也要維護(hù)。并且索引越多,維護(hù)成本越高。

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

16.1 高頻查詢字段建索引

例如:

用戶名
手機(jī)號(hào)
訂單號(hào)

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

例如:

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

全表掃描更快。

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

例如:

手機(jī)號(hào)
身份證號(hào)

不適合:

性別

因?yàn)椋?/p>

重復(fù)值太多

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

推薦:

(name,age)

而不是:

name
age

16.5 盡量使用覆蓋索引

減少回表。

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

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)

十八、面試高頻問(wèn)題

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

因?yàn)闇p少了數(shù)據(jù)掃描次數(shù)。

18.2 MySQL索引底層是什么?

B+Tree

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

聚簇索引:

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

非聚簇索引:

索引存主鍵值
需要回表

18.4 什么是回表查詢?

先查普通索引:

再查主鍵索引。

18.5 什么是最左前綴原則?

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

十九、總結(jié)

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

它的本質(zhì):

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

重點(diǎn)一定要掌握:

  • B+樹(shù)

  • 聚簇索引

  • 聯(lián)合索引

  • 最左前綴

  • 覆蓋索引

  • 索引失效

對(duì)于開(kāi)發(fā)者來(lái)說(shuō),真正的高性能系統(tǒng):

并不是:

代碼寫(xiě)得多復(fù)雜

而是:

SQL是否高效
索引是否合理

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

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

相關(guān)文章

最新評(píng)論

镇坪县| 赣州市| 区。| 奉化市| 泰州市| 吴江市| 安国市| 荣昌县| 南宫市| 寻乌县| 康定县| 江都市| 玉树县| 福贡县| 赤峰市| 邵阳县| 武宁县| 桂阳县| 洱源县| 卢湾区| 于都县| 湖北省| 泸水县| 科尔| 柳林县| 贵州省| 内江市| 宝鸡市| 台安县| 文安县| 望江县| 金山区| 姜堰市| 乡宁县| 奎屯市| 宁海县| 民和| 永和县| 卢龙县| 西宁市| 屏边|