MySQL存储引擎和索引
约 772 字大约 3 分钟
innodb和myisam区别?
innodb
- 支持事务,支持外键,因此数据的完整性、一致性更高。
- 支持行级别的锁和表级别的锁。
- 支持读写并发,写不阻塞读(MVCC)。
- 特殊的索引存放方式,可以减少 IO,提升查询效率。
- 根据主键索引组织数据存储,数据和索引存储在一个文件中(user_innodb.ibd)
适合:经常更新的表,存在并发读写或者有事务处理的业务系统。
myisam
- 支持表级别的锁(插入和更新会锁表)。不支持事务。
- 拥有较高的插入(insert)和查询(select)速度。
- 存储了表的行数(count 速度更快)。 (怎么快速向数据库插入 100 万条数据?我们有一种先用 MyISAM 插入数据,然后修改存储引擎为 InnoDB 的操作。)
- 数据文件和索引文件分开存储(user_myisam.MYI, user_myisam.MYD)
适合:只读之类的数据分析的项目。
索引创建原则:
- 在用于 where 判断 order 排序和 join 的(on)字段上创建索引
- 索引的个数不要过多。 ------浪费空间,更新变慢。
- 区分度低的字段,例如性别,不要建索引。 ------离散度太低,导致扫描行数过多。
- 频繁更新的值,不要作为主键或者索引。 ------页分裂
- 组合索引把散列性高(区分度高)的值放在前面。
- 创建复合索引,而不是修改单列索引。
- 过长的字段,怎么建立索引?
使用全文索引或前缀索引 - 为什么不建议用无序的值(例如身份证. UUID )作为索引?
B+树的叶子节点之间是有序的,使用有序值作为索引,可以减少合并和分裂。
无法使用索引的场景:
索引列上使用函数(replace\SUBSTR\CONCAT\sum count avg)、 表达式、计算(+ - * /):
字符串不加引号,出现隐式转换
like 条件中前面带%
负向查询
脏读不可重复读和幻读
脏读: 读取到其他事务未提交的数据,导致前后两次读取数据不一致;不可重复读: 读取到了其他事务已提交的数据,导致前后两次读取数据不一致;幻读: 前后两次读取数据数据不一致,是由于其他事务造成的。
四种隔离级别

MVCC: 只能查找创建时间小于等于当前事务 ID 的数据,和删除时间大于当前事务 ID 的行
。