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

MySQL三種常用存儲(chǔ)引擎InnoDB、MyISAM、Memory深度解析

 更新時(shí)間:2026年05月31日 15:20:18   作者:身如柳絮隨風(fēng)揚(yáng)  
在線教程千萬(wàn)篇,為什么你的 SQL 還是慢?因?yàn)闆]理解存儲(chǔ)引擎的底層機(jī)制,本文將帶你從源碼角度徹底搞懂 InnoDB 行鎖、聚簇索引,并給出生產(chǎn)環(huán)境的最優(yōu)選型,需要的朋友可以參考下

1. 前言:存儲(chǔ)引擎就是 MySQL 的“發(fā)動(dòng)機(jī)”

MySQL 區(qū)別于其他關(guān)系數(shù)據(jù)庫(kù)的最大特色是其 插件式存儲(chǔ)引擎 架構(gòu)。你可以根據(jù)不同的表需求(事務(wù)、并發(fā)、數(shù)據(jù)一致性、臨時(shí)性)選擇不同的引擎,從而像換汽車發(fā)動(dòng)機(jī)一樣靈活匹配性能。

本文聚焦于最常用的三種引擎:InnoDB、MyISAMMemory。讀完你將獲得:

  • ? 三個(gè)引擎的完整對(duì)比表(包括鎖機(jī)制、索引實(shí)現(xiàn)、事務(wù)支持)
  • ? InnoDB 行鎖的真相:為什么索引是行鎖的生命線?
  • ? 聚簇索引 vs 非聚簇索引的底層 B+ 樹圖解
  • ? 真實(shí)生產(chǎn)場(chǎng)景的選型決策樹
  • ? 如何避免 InnoDB 的“表鎖陷阱”

2. 三引擎速覽表

特性InnoDBMyISAMMemory
事務(wù)? ACID??
鎖粒度行鎖 + 表鎖表鎖表鎖
外鍵???
MVCC???
數(shù)據(jù)持久化磁盤磁盤內(nèi)存(重啟丟失)
索引類型聚簇索引(主鍵數(shù)據(jù)一體)非聚簇索引(數(shù)據(jù)指針)默認(rèn)哈希 / B 樹
COUNT(*) 速度需掃描(慢)變量存儲(chǔ)(極快)需掃描
全文索引5.6+ 支持??
適用場(chǎng)景OLTP(訂單、賬戶、支付)讀多寫少(報(bào)表、日志)臨時(shí)表、緩存、session

3. InnoDB vs MyISAM:全方位對(duì)決

3.1 事務(wù)支持

InnoDB 通過(guò) redo log(重做日志)和 undo log(回滾日志)實(shí)現(xiàn) ACID。MyISAM 不支持事務(wù),因此在系統(tǒng)崩潰后容易丟失數(shù)據(jù)或損壞表。

3.2 鎖機(jī)制的差異(核心重點(diǎn))

  • MyISAM:只支持表鎖。讀寫相互阻塞,寫操作會(huì)鎖全表,并發(fā)寫入能力極弱。
  • InnoDB:默認(rèn)行鎖(基于索引),同時(shí)保留表鎖(用于 DDL 或未使用索引的 DML)。

重要:InnoDB 的行鎖是鎖在 索引項(xiàng) 上的。如果 SQL 中的 WHERE 條件沒有用到索引,InnoDB 將使用 表鎖,這會(huì)瞬間殺死并發(fā)性能。

-- 行鎖示例(id 為主鍵)
UPDATE user SET name='Alice' WHERE id = 100;  -- 僅鎖 id=100 這一行

-- 表鎖示例(age 字段無(wú)索引)
UPDATE user SET name='Bob' WHERE age = 25;    -- 鎖整個(gè)表!

生產(chǎn)建議:所有用于 WHERE、JOIN、ORDER BY 的條件字段,必須建立索引。同時(shí),可以使用 EXPLAIN 檢查是否命中索引。

3.3 索引結(jié)構(gòu):聚簇 vs 非聚簇

InnoDB 聚簇索引

  • 表數(shù)據(jù)和主鍵索引存儲(chǔ)在一顆 B+ 樹的葉子節(jié)點(diǎn)中。
  • 主鍵查找只需一次 B+ 樹遍歷,速度極快。
  • 輔助索引(二級(jí)索引)的葉子節(jié)點(diǎn)存儲(chǔ)的是主鍵值,因此需要 回表 查詢主鍵索引,效率略低。

MyISAM 非聚簇索引

  • 數(shù)據(jù)和索引完全分離。索引 B+ 樹的葉子節(jié)點(diǎn)存儲(chǔ)的是數(shù)據(jù)行的物理地址。
  • 主鍵索引和輔助索引結(jié)構(gòu)相同,沒有回表開銷,但每次查找都需要二次尋址(索引->指針->數(shù)據(jù)行)。

3.4 其他差異

  • 外鍵:InnoDB 支持外鍵約束,適合強(qiáng)一致性業(yè)務(wù);MyISAM 不支持。
  • 崩潰恢復(fù):InnoDB 通過(guò) redo log 自動(dòng)恢復(fù)未完成事務(wù);MyISAM 需要手動(dòng) REPAIR TABLE。
  • 壓縮:MyISAM 支持表壓縮(myisampack),適合歸檔數(shù)據(jù);InnoDB 雖然支持頁(yè)壓縮,但不夠便捷。

4. InnoDB 行鎖的深度剖析

4.1 行鎖在索引上的具體實(shí)現(xiàn)

InnoDB 中,行鎖是通過(guò)給索引記錄加 記錄鎖(Record Lock) 實(shí)現(xiàn)的。如果是范圍查詢,還會(huì)加上 間隙鎖(Gap Lock)(防止幻讀)和 臨鍵鎖(Next-Key Lock)

只有滿足以下條件,才能使用行鎖:

  1. SQL 語(yǔ)句的 WHERE 條件命中了某個(gè)索引(可以是主鍵、唯一索引、普通索引)。
  2. 該索引不是“失效”狀態(tài)(如函數(shù)操作、類型隱式轉(zhuǎn)換等)。

4.2 為什么無(wú)索引會(huì)升級(jí)為表鎖?

因?yàn)?InnoDB 需要知道哪些行要被修改。沒有索引時(shí),它無(wú)法高效定位到具體行,只能鎖住整個(gè)表以確保正確性。

案例:高并發(fā)環(huán)境下,誤執(zhí)行一次無(wú)索引的 UPDATE,可能瞬間鎖表,導(dǎo)致所有寫操作阻塞,引發(fā)生產(chǎn)故障。

4.3 行鎖 + 間隙鎖避免幻讀

在 REPEATABLE READ 隔離級(jí)別下,InnoDB 使用 Next-Key Lock(記錄鎖+間隙鎖)來(lái)防止幻讀。例如:

SELECT * FROM user WHERE age BETWEEN 20 AND 30 FOR UPDATE;

InnoDB 不僅鎖住符合條件行的索引記錄,還鎖住了這些記錄之間的“間隙”,使得其他事務(wù)無(wú)法插入符合條件的新行。

5. Memory 引擎的“快”與“險(xiǎn)”

  • 優(yōu)點(diǎn):數(shù)據(jù)存儲(chǔ)于內(nèi)存,哈希索引,讀寫極快,尤其適合小表的高頻等值查詢。
  • 缺點(diǎn):重啟數(shù)據(jù)丟失;只支持表鎖,高并發(fā)寫入下鎖競(jìng)爭(zhēng)嚴(yán)重;不支持 TEXT/BLOB 字段。
  • 使用場(chǎng)景:臨時(shí)表、緩存表(如 session 存儲(chǔ))、只讀統(tǒng)計(jì)中間結(jié)果。

6. 實(shí)戰(zhàn)選型:一張決策樹幫你選對(duì)引擎

結(jié)論:對(duì)于 99% 的互聯(lián)網(wǎng)業(yè)務(wù),直接選擇 InnoDB。MyISAM 只適合純粹的歸檔或日志表。Memory 用于臨時(shí)計(jì)算結(jié)果。

7. 高頻面試題與踩坑點(diǎn)

Q1:InnoDB 行鎖升級(jí)為表鎖的常見原因?

  • WHERE 條件字段無(wú)索引
  • 索引字段被隱式類型轉(zhuǎn)換(如 WHERE phone = 123,但 phone 是 varchar)
  • 對(duì)索引字段使用函數(shù)(WHERE DATE(create_time) = '2025-01-01'

Q2:MyISAM 的COUNT(*)為什么快?

因?yàn)?MyISAM 內(nèi)部存儲(chǔ)了表的精確行數(shù)(一個(gè)變量)。而 InnoDB 因?yàn)橛?MVCC,不同事務(wù)看到行數(shù)不同,必須實(shí)時(shí)掃描。

Q3:為什么建表推薦使用 InnoDB?

因?yàn)?InnoDB 是目前唯一同時(shí)支持事務(wù)、行鎖、MVCC、崩潰恢復(fù)、外鍵的引擎,且隨著版本迭代性能表現(xiàn)優(yōu)異。

Q4:Memory 引擎能否作為正式業(yè)務(wù)表?

不能。一旦 mysqld 重啟,所有數(shù)據(jù)丟失??纱钆?init_file 選項(xiàng)啟動(dòng)時(shí)導(dǎo)入,但依然不推薦用于核心業(yè)務(wù)。

8. 總結(jié)與最佳實(shí)踐

  • 默認(rèn)引擎:除非有特殊理由,一律使用 InnoDB。
  • 索引是行鎖的開關(guān):確保 DML 語(yǔ)句的條件字段有索引,避免 InnoDB 退化為表鎖。
  • MyISAM 僅用于只讀大表:例如歷史數(shù)據(jù)報(bào)表、歸檔表。
  • Memory 僅用于臨時(shí)對(duì)象:如 CREATE TEMPORARY TABLE ... ENGINE=MEMORY。

牢記:SQL 慢,往往不是因?yàn)橐姹旧?,而是因?yàn)樗饕O(shè)計(jì)或鎖機(jī)制沒有用對(duì)。希望本文幫你徹底掌握 MySQL 存儲(chǔ)引擎的內(nèi)功心法。

附錄:查看當(dāng)前表的引擎

SHOW TABLE STATUS WHERE Name = 'your_table'\G

修改表引擎

ALTER TABLE your_table ENGINE = InnoDB;

以上就是MySQL三種常用存儲(chǔ)引擎InnoDB、MyISAM、Memory深度解析的詳細(xì)內(nèi)容,更多關(guān)于MySQL存儲(chǔ)引擎InnoDB、MyISAM、Memory的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 一次非法關(guān)機(jī)導(dǎo)致mysql數(shù)據(jù)表?yè)p壞的實(shí)例解決

    一次非法關(guān)機(jī)導(dǎo)致mysql數(shù)據(jù)表?yè)p壞的實(shí)例解決

    本文介紹由于非法硬件關(guān)機(jī),造成了mysql的數(shù)據(jù)表?yè)p壞,數(shù)據(jù)庫(kù)不能正常運(yùn)行的一個(gè)實(shí)例,接下來(lái)是作者排查錯(cuò)誤的過(guò)程,希望對(duì)大家能有所幫助
    2013-01-01
  • MySQL更新DATETIME/TIMESTAMP字段日期部分而保留時(shí)間部分的四種方法

    MySQL更新DATETIME/TIMESTAMP字段日期部分而保留時(shí)間部分的四種方法

    在 MySQL 中,若要更新 DATETIME 或 TIMESTAMP 字段的?日期部分?(年月日),同時(shí)保持?時(shí)間部分?(時(shí)分秒)不變,主要有以下幾種常用且高效的方法,需要的朋友可以參考下
    2026-06-06
  • MySQL中的用戶和權(quán)限管理詳解(看這一篇就足夠了!)

    MySQL中的用戶和權(quán)限管理詳解(看這一篇就足夠了!)

    MySQL權(quán)限管理是數(shù)據(jù)庫(kù)安全性的重要組成部分,它決定了哪些用戶可以對(duì)數(shù)據(jù)庫(kù)執(zhí)行哪些操作,這篇文章主要介紹了MySQL中用戶和權(quán)限管理的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-10-10
  • MySQL索引失效的幾種情況小結(jié)

    MySQL索引失效的幾種情況小結(jié)

    本文主要介紹了MySQL索引失效的幾種情況小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • 利用frm和ibd文件恢復(fù)mysql表數(shù)據(jù)的詳細(xì)過(guò)程

    利用frm和ibd文件恢復(fù)mysql表數(shù)據(jù)的詳細(xì)過(guò)程

    總是遇到mysql服務(wù)意外斷開之后導(dǎo)致mysql服務(wù)無(wú)法正常運(yùn)行的情況,使用Navicat工具查看能夠看到里面的庫(kù)和表,但是無(wú)法獲取數(shù)據(jù)記錄,提示數(shù)據(jù)表不存在,所以本文給大家介紹了利用frm和ibd文件恢復(fù)mysql表數(shù)據(jù)的詳細(xì)過(guò)程,需要的朋友可以參考下
    2024-04-04
  • Windows下MySQL8.0.18安裝教程(圖解)

    Windows下MySQL8.0.18安裝教程(圖解)

    這篇文章主要介紹了Windows下MySQL8.0.18安裝教程,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-11-11
  • MySQL中數(shù)據(jù)查詢語(yǔ)句整理大全

    MySQL中數(shù)據(jù)查詢語(yǔ)句整理大全

    查詢語(yǔ)句是以后在工作中使用最多也是最復(fù)雜的用法,如何精準(zhǔn)的查詢出想要的結(jié)果以及用最合理的邏輯去查詢尤為重要,下面這篇文章主要給大家介紹了關(guān)于MySQL中數(shù)據(jù)查詢語(yǔ)句的相關(guān)資料,需要的朋友可以參考下
    2023-04-04
  • mysql8.4版本mysql_native_password無(wú)法連接問(wèn)題解決

    mysql8.4版本mysql_native_password無(wú)法連接問(wèn)題解決

    用dbeaver可以直接連接,但是用NAVICAT連接后報(bào)錯(cuò),本文主要介紹了mysql8.4版本mysql_native_password無(wú)法連接問(wèn)題解決,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-07-07
  • MySQL多表查詢、事務(wù)與索引的實(shí)踐與應(yīng)用操作

    MySQL多表查詢、事務(wù)與索引的實(shí)踐與應(yīng)用操作

    本文圍繞MySQL數(shù)據(jù)庫(kù)操作展開,通過(guò)構(gòu)建部門與員工管理、餐飲業(yè)務(wù)相關(guān)的數(shù)據(jù)庫(kù)表,并填充測(cè)試數(shù)據(jù),系統(tǒng)地闡述了多表查詢的多種方式,包括內(nèi)連接、外連接和不同類型的子查詢,同時(shí)介紹了事務(wù)的處理以及索引的創(chuàng)建、查詢和刪除操作,感興趣的朋友一起看看吧
    2025-04-04
  • 詳細(xì)分析mysql MDL元數(shù)據(jù)鎖

    詳細(xì)分析mysql MDL元數(shù)據(jù)鎖

    這篇文章主要介紹了mysql MDL元數(shù)據(jù)鎖的相關(guān)資料,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-08-08

最新評(píng)論

婺源县| 翼城县| 延寿县| 台北县| 溧水县| 克山县| 赞皇县| 寻甸| 徐汇区| 兰考县| 鹤峰县| 泰和县| 龙泉市| 宜昌市| 牡丹江市| 夏邑县| 安吉县| 五家渠市| 宣化县| 镇安县| 香格里拉县| 新沂市| 南投市| 方山县| 红安县| 耿马| 雷山县| 新建县| 太原市| 宜城市| 共和县| 德江县| 文水县| 定陶县| 宜君县| 义马市| 吉隆县| 滦南县| 镇赉县| 驻马店市| 长武县|