MySQL Myisam引擎和Innodb引擎的区别

MySQL Myisam和Innodb的区别

MySQL 区别于其他数据库的很重要的一个特点就是插件式的表存储引擎,其基于表,而不是数据库。由于每个存储引擎都有其特点,最常见的是 Innodb 引擎和 Myisam 引擎,因此我们可以针对每一张表来挑选最合适的存储引擎。

两者区别对照表:

Myisam Innodb
5.5版本前默认引擎 5.5后默认引擎
索引数据结构 B+树 B+树
索引类型 非聚集索引 聚集索引
事务 不支持 支持(提交、回滚)
外键 不支持 支持
锁的级别 表级锁,不会出现死锁,但并发性能差 行级锁,能抗更高并发。同时还通过MVVC多版本控制来提高并发读写性能。可能发生死锁,消耗资源多。如果一条语句无法确定要扫描的范围,也会锁定整张表
CRUD 查询速度快,在索引树找到物理地址取出数据 查询比Myisam慢,可能需要二次查询。行级锁,大量写操作速度快。
表行数 单独记录,如果有where也会全表扫描 需全表扫描,select count(*) from table
数据恢复能力 数据恢复慢 有完善的数据快速恢复能力
delete from table时 会直接重建表 会一行一行的删除,但是可以用truncate table代替
适用场景 1.查询频繁
2.大量查总count
3.没有事务操作
1.并发量大,需要高可用
2.表更新频繁(更改、插入、删除)
3.需要事务

聚集索引、非聚集索引查询过程的比较

非聚集索引查询过程

索引和数据是分开的

1,先沿着索引树找到数据的物理位置

2,到物理位置取出数据【又叫数据回行、回表】

当我们为某个字段添加索引时,我们同样会生成对应字段的索引树,该字段的索引树的叶子节点同样是记录了对应数据的物理地址,然后也是拿着这个物理地址去数据文件里定位到具体的数据记录。

注:Myisam支持没有主键的表存在。

聚集索引查询过程

索引和数据是在一起的,在同一个文件中

聚集索引中,数据存储在主键Key索引树的叶子节点上。如果创建了其他列的索引,例如username,也会生成一颗username索引树,但是username索引树的叶子节点只存username和主键Key,不存其他字段,如果就只需要username和Key属性,则取走就可以了【索引覆盖】;如果需要除username和Key之外的属性,需要拿着这个Key沿着主键Key索引树查叶子节点,再取走数据,也就是需要两次查询。

1,用主键Key查询时,找到Key的叶子节点取出数据即可。

2,用其他索引列(username)查询时,在username索引树中找到主键Key,拿着Key再走主键索引树,取走数据。如果只需要username和Key两个属性,那么在username索引树上取走就可以了【索引覆盖】。

注:如果没有指定主键,Innodb会为每行自动生成一个6字节的ROWID作为主键建立主键索引树。

可以做索引的数据结构有:

1,hash表

查询速度非常快,时间复杂度O(1)。hash冲突一般用链地址法解决。

最终被Pass了,原因是对范围查询效率很差,范围查询时要挨个比较。

2,二叉搜索树—>红黑树—>AVL树—>B树—>B+树

二叉排序树平均复杂度log(n),但极端情况会退化为线性表O(n)的复杂度,导致检索性能降低。能范围查询。

红黑树和AVL树通过自旋维持平衡,红黑树有右倾问题,AVL树不存在极端情况,AVL有不错的检索性能又能范围查询,但是为什么Mysql没选AVL?因为AVL每个节点都只存一个数据,而一次磁盘IO读一个数据和读100个数据消耗的时间基本一致,那么应该尽可能在一次磁盘IO中多读一点数据到内存,尽量减少磁盘IO的次数。

B树一个节点存储了多个数据,尽可能的减少了磁盘IO次数,有高效的检索速度,且支持范围查询。时间复杂度h·log(n),h表示树高,n表示一个节点存的数据量。

B树已经不错了,但为了更高的检索性能,推出了B+树。B+树的非叶子节点存的是索引,索引比原数据小,所以一个节点中能存更多的索引,真实数据都在叶子节点,叶子节点之间用链表横向连接,支持范围查询。和B树相比,B+索引树更矮,只需很少的磁盘IO次数,大大提高了检索效率。

为什么不给所有字段都加索引?

给字段加索引以后,查询性能有所提升,那干脆给所有字段都加上索引算了呗,全面提升查询性能!

大戳特戳辽!!原因有二:

1,太多的索引占用更多的磁盘空间和内存空间,索引在调用时被加载到内存,对于大型表可能影响读取性能

2,影响写入的速度(插入/删除/更新),每更新一条记录,也要更新它的索引树。因此,索引越多写的性能越慢。

什么时候需要给表的字段加索引:

1,较频繁的作为查询条件的字段应该创建索引。

2,经常排序、分组的字段应该创建索引。

3,更新非常频繁的字段不适合创建索引。(要更新索引树,影响写性能)

索引为什么能提高排序速度?

MySQL 中的Innodb、Myisam都是基于B+树建立的索引树,B+树的叶子节点用链表横向串联起来,叶子节点本身就是排好序的,从左往右一次递增,所以执行SQL语句排序时取出的数据就是排序好的。

补一个Memory存储引擎

Memory引擎是把数据放在内存中,一旦服务关闭,表中数据就会丢失。Memory默认使用hash索引,有非常快的查询速度[O(1)],但范围查询性能很差。
Memory支持的数据类型有限制,不支持TEXT/BLOB等,锁的级别是表级锁,扛不住很高的并发。它主要用于那些内容变化不频繁的数据,现在MongoDB、Redis等NOSQL数据库越来越流行,Memory存储引擎的使用场景变得越来越少。

其他存储引擎:
MERGE(分区表)
BLACKHOLE(黑洞引擎)
CSV
ARCHIVE

posted @ 2020-06-17 12:01  961897  阅读(369)  评论(0编辑  收藏  举报