Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MySQL存储引擎InnoDB、MyISAM、Memory

MySQL三种常用存储引擎InnoDB、MyISAM、Memory深度解析

作者:身如柳絮随风扬

在线教程千万篇,为什么你的 SQL 还是慢?因为没理解存储引擎的底层机制,本文将带你从源码角度彻底搞懂 InnoDB 行锁、聚簇索引,并给出生产环境的最优选型,需要的朋友可以参考下

1. 前言:存储引擎就是 MySQL 的“发动机”

MySQL 区别于其他关系数据库的最大特色是其 插件式存储引擎 架构。你可以根据不同的表需求(事务、并发、数据一致性、临时性)选择不同的引擎,从而像换汽车发动机一样灵活匹配性能。

本文聚焦于最常用的三种引擎:InnoDBMyISAMMemory。读完你将获得:

2. 三引擎速览表

特性InnoDBMyISAMMemory
事务✅ ACID
锁粒度行锁 + 表锁表锁表锁
外键
MVCC
数据持久化磁盘磁盘内存(重启丢失)
索引类型聚簇索引(主键数据一体)非聚簇索引(数据指针)默认哈希 / B 树
COUNT(*) 速度需扫描(慢)变量存储(极快)需扫描
全文索引5.6+ 支持
适用场景OLTP(订单、账户、支付)读多写少(报表、日志)临时表、缓存、session

3. InnoDB vs MyISAM:全方位对决

3.1 事务支持

InnoDB 通过 redo log(重做日志)和 undo log(回滚日志)实现 ACID。MyISAM 不支持事务,因此在系统崩溃后容易丢失数据或损坏表。

3.2 锁机制的差异(核心重点)

重要:InnoDB 的行锁是锁在 索引项 上的。如果 SQL 中的 WHERE 条件没有用到索引,InnoDB 将使用 表锁,这会瞬间杀死并发性能。

-- 行锁示例(id 为主键)
UPDATE user SET name='Alice' WHERE id = 100;  -- 仅锁 id=100 这一行

-- 表锁示例(age 字段无索引)
UPDATE user SET name='Bob' WHERE age = 25;    -- 锁整个表!

生产建议:所有用于 WHERE、JOIN、ORDER BY 的条件字段,必须建立索引。同时,可以使用 EXPLAIN 检查是否命中索引。

3.3 索引结构:聚簇 vs 非聚簇

InnoDB 聚簇索引

MyISAM 非聚簇索引

3.4 其他差异

4. InnoDB 行锁的深度剖析

4.1 行锁在索引上的具体实现

InnoDB 中,行锁是通过给索引记录加 记录锁(Record Lock) 实现的。如果是范围查询,还会加上 间隙锁(Gap Lock)(防止幻读)和 临键锁(Next-Key Lock)

只有满足以下条件,才能使用行锁:

  1. SQL 语句的 WHERE 条件命中了某个索引(可以是主键、唯一索引、普通索引)。
  2. 该索引不是“失效”状态(如函数操作、类型隐式转换等)。

4.2 为什么无索引会升级为表锁?

因为 InnoDB 需要知道哪些行要被修改。没有索引时,它无法高效定位到具体行,只能锁住整个表以确保正确性。

案例:高并发环境下,误执行一次无索引的 UPDATE,可能瞬间锁表,导致所有写操作阻塞,引发生产故障。

4.3 行锁 + 间隙锁避免幻读

在 REPEATABLE READ 隔离级别下,InnoDB 使用 Next-Key Lock(记录锁+间隙锁)来防止幻读。例如:

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

InnoDB 不仅锁住符合条件行的索引记录,还锁住了这些记录之间的“间隙”,使得其他事务无法插入符合条件的新行。

5. Memory 引擎的“快”与“险”

6. 实战选型:一张决策树帮你选对引擎

结论:对于 99% 的互联网业务,直接选择 InnoDB。MyISAM 只适合纯粹的归档或日志表。Memory 用于临时计算结果。

7. 高频面试题与踩坑点

Q1:InnoDB 行锁升级为表锁的常见原因?

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

因为 MyISAM 内部存储了表的精确行数(一个变量)。而 InnoDB 因为有 MVCC,不同事务看到行数不同,必须实时扫描。

Q3:为什么建表推荐使用 InnoDB?

因为 InnoDB 是目前唯一同时支持事务、行锁、MVCC、崩溃恢复、外键的引擎,且随着版本迭代性能表现优异。

Q4:Memory 引擎能否作为正式业务表?

不能。一旦 mysqld 重启,所有数据丢失。可搭配 init_file 选项启动时导入,但依然不推荐用于核心业务。

8. 总结与最佳实践

牢记:SQL 慢,往往不是因为引擎本身,而是因为索引设计或锁机制没有用对。希望本文帮你彻底掌握 MySQL 存储引擎的内功心法。

附录:查看当前表的引擎

SHOW TABLE STATUS WHERE Name = 'your_table'\G

修改表引擎

ALTER TABLE your_table ENGINE = InnoDB;

以上就是MySQL三种常用存储引擎InnoDB、MyISAM、Memory深度解析的详细内容,更多关于MySQL存储引擎InnoDB、MyISAM、Memory的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文