[db:标题]
摘要:MyISAM和InnoDB的区别 事务能力(这是最根本的区别!) InnoDB:支持事务(ACID),就像银行转账,要么全部成功,要么全部失败,保证数据安全 MyISAM:不支持事务,就像手写账本,“写错一笔就全盘皆输” 锁机制(并发性能的
MyISAM和InnoDB的区别
事务能力(这是最根本的区别!)
InnoDB:支持事务(ACID),就像银行转账,要么全部成功,要么全部失败,保证数据安全
MyISAM:不支持事务,就像手写账本,“写错一笔就全盘皆输”
锁机制(并发性能的关键)
InnoDB:行级锁,只锁你要操作的行,别人还能同时操作其他行
MyISAM:表级锁,你一写,整张表都锁住,别人只能干等
外键支持
InnoDB:支持外键,能自动保证关联表数据一致
MyISAM:不支持外键,需要靠程序员自己写逻辑
读写性能
InnoDB:读写都均衡,适合高并发场景
MyISAM:读快写慢,写操作会锁整张表,适合"读多写少"的场景
故障恢复
InnoDB:有完善的崩溃恢复机制,不怕突然断电
MyISAM:断电后可能要手动修复,就像突然断电的Excel文档
存储方式
InnoDB:数据和索引一起存,用.ibd文件
MyISAM:数据、索引、表结构分开存,分别是.MYD、.MYI、.frm
适用场景
InnoDB:适合高并发读写、需要事务和外键的场景,例如:电商、银行系统。写入性能更稳定(行锁减少锁冲突)。
MyISAM:适合读多写少的场景(如报表、日志系统、数据仓库)。
批量查询速度可能更快(无事务开销,表锁简单)。
总结
维度
MyISAM
InnoDB
事务
不支持
支持(ACID、提交/回滚)
锁粒度
表级锁
行级锁(含间隙锁)
外键
不支持
支持
崩溃恢复
仅依赖检查/修复表(REPAIR TABLE)
redo/undo 日志自动崩溃恢复
索引类型
非聚簇索引(数据与索引分离)
聚簇索引(主键即数据)
存储文件
.MYD(数据)+.MYI(索引)
.ibd(单表空间)或共享表空间
COUNT(*)
内置计数器,瞬间返回(无WHERE条件下)
InnoDB 执行 COUNT() 需要扫描可用索引或聚簇索引,数据量越大耗时越长
全文索引
5.6 之前仅 MyISAM 支持原生全文索引
5.6+ 支持,性能更优
压缩表
myisampack 只读压缩
支持行格式压缩(ROW_FORMAT=COMPRESSED)
适用场景
读多写少、无事务、静态报表
高并发读写、需要事务/外键/恢复保障
如何选择
优先InnoDB:现代MySQL的默认引擎,适合99%的场景,尤其是需要事务、并发或数据安全的应用。
例外用MyISAM:仅当系统以读为主、无需事务且追求极简优化时(如静态报表),但已逐渐被InnoDB+缓存或Aria(MariaDB)替代。
MySQL 8.0已标记MyISAM为废弃引擎,仅保留InnoDB作为核心引擎。
MySQL的一条SQL语句的执行过程是怎么样的?
先来看一张总览图
主要步骤:客户端发送 SQL → 连接器 → 查询缓存(8.0 已移除)→ 解析器 → 预处理器 → 优化器 → 执行器 → 存储引擎 → 返回结果
使用连接器
通过客户端/服务器通信协议,客户端与 MySQL 建立 TCP 连接。验证用户名、密码、权限。每个连接对应一个线程(MySQL 是线程模型)。
查询缓存(Query Cache)(MySQL 8.0 已移除)
如果开启,会检查是否执行过完全相同的 SQL。
命中则直接返回结果,跳过后续步骤。
但由于命中率低、锁竞争严重,8.0 被废弃(实际在 5.7 起已默认关闭)。
解析器(Parser)
词法分析:将 SQL 字符串拆成 token。
语法分析:构建语法树(AST),检查语法是否正确。比如:select * form user (form写错了应该是from)→ 会报错 syntax error。
预处理器(Preprocessor)
语义分析:检查表、列是否存在。别名是否合法。展开视图、子查询等。
权限验证:检查用户是否有访问表的权限。
优化器(Optimizer)
这里是核心阶段:决定怎么执行这条 SQL。
主要工作包括:
选择索引(哪个索引最优)。
决定 join 顺序(先查 A 表还是 B 表)。
是否使用覆盖索引、ICP、MRR 等优化。
生成执行计划(Execution Plan)。
你可以用 EXPLAIN 或 EXPLAIN FORMAT=JSON 查看优化器的选择。
执行器(Executor)
根据执行计划,调用存储引擎的接口。
逐行读取数据(或通过索引加速)。
执行 WHERE 过滤、排序、聚合、LIMIT 等操作。
对于 UPDATE/DELETE,还会加锁(行锁、间隙锁等)。
存储引擎(如 InnoDB)
这里真正负责数据在磁盘与内存间的读写。
