最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
MySQL中MyISAM的索引文件和数据文件为什么是分离存储的?
时间:2026-07-12 09:50:47 编辑:袖梨 来源:一聚教程网
MyISAM索引与数据分离是刻意设计:.MYI存B+Tree索引(叶子存磁盘地址),.MYD为纯堆表;查询需两次I/O,全表扫描快;不支持事务、行锁、崩溃恢复,故无需聚簇;写多并发高时性能下降,且不支持覆盖索引。
MyISAM 的索引和数据分离,不是设计缺陷,而是刻意为之的轻量级取舍:它压根不打算支持事务、行锁或崩溃恢复,所以不需要把数据和索引绑死在一块。
MyISAM 的 .MYI 和 .MYD 各自只干一件事
这种分离直接体现在文件职责上:
-
.MYI文件只存 B+Tree 索引结构,叶子节点里塞的是地址(比如0x1A2B3C这样的磁盘偏移量),不是数据本身 -
.MYD文件就是个纯堆表,按插入顺序线性写入,不排序、不聚簇、不维护逻辑顺序 - 查
SELECT * FROM t WHERE id = 123时,先读.MYI找到地址,再跳转去.MYD读那一行 —— 两次 I/O - 但
SELECT * FROM t全表扫描时,完全绕过.MYI,直接顺序读.MYD,速度极快
为什么不像 InnoDB 那样把数据塞进叶子节点?
InnoDB 必须聚簇,是因为它要靠主键组织物理存储来支撑 MVCC、行锁、崩溃恢复。MyISAM 没这些需求:
- 不支持事务 → 不需要
undo log/redo log,也不依赖“主键 ⇔ 物理位置”强绑定 - 只支持表锁 → 加锁对象是整个
.MYD文件,无需按主键精确定位某一行 - 崩溃后无法安全恢复 →
.MYI损坏就只能REPAIR TABLE,没机制重建地址映射 - 所以它选择最简路径:索引归索引,数据归数据,各自独立更新,逻辑清晰、实现简单
分离带来的实际代价常被低估
写多或并发高时,问题立刻暴露:
- 每次
UPDATE或DELETE都得同时改.MYI和.MYD,两个文件可能落在不同磁盘块,随机 I/O 增加 -
INSERT会锁住整个.MYD,其他读写全部阻塞 -
OPTIMIZE TABLE实际是重建两个文件,期间表不可写,且临时空间暴涨 - 真正容易被忽略的是:MyISAM 不支持覆盖索引优化。哪怕
SELECT name FROM t WHERE email = 'x@y',且(email, name)有联合索引,它仍要回.MYD查 —— 因为索引叶子节点里只有地址,不存任何列值
这个“地址即一切”的模型,决定了 MyISAM 的能力边界:适合读多写少、可接受表锁、能容忍修复失败的场景。一旦写入压力上来,或者需要强一致性,分离结构就成了硬伤,而不是特色。
相关文章
- 王者荣耀世界零氪玩家如何生存 07-28
- 快手极速版怎么绑定手机号 07-28
- 明日方舟和轻松小熊联动活动内容一览 07-28
- 逆战未来黎明之光 逆战未来黎明之光玩法机制与新手入门指南 07-28
- 植物大战僵尸融合版毁灭土豆地雷介绍 07-28
- 逆战未来飓风之龙 逆战未来飓风之龙武器获取方法详解 07-28