美文网首页spring boot数据库
myisam和innodb的差异

myisam和innodb的差异

作者: 无聊之园 | 来源:发表于2019-04-28 10:21 被阅读23次

    mysiam和innodb索引结构的差异

    一、myisam的索引和记录是分开存储,数据记录是聚集存储在一块区域,索引以b+树单独存储,叶子节点存储索引以及指向数据记录的指针,myisam的主键索引和普通索引结构类似,数据记录和索引都是分开存储。
    二、innodb的表必定会有一个聚簇索引,有主键,则主键是聚簇索引,没有主键则第一个非null,unique列是聚簇索引,否则,rowid为聚簇索引。聚簇索引为b+树结构,叶子节点,存储聚簇索引以及实际的数据记录。普通索引也为b+树结构,叶子节点存储普通索引以及聚簇索引。通过聚簇索引找数据会非常快,因为,聚簇索引的叶子节点直接就存储了记录,通过普通索引找数据,则会先通过普通索引找到聚簇索引,再通过聚簇索引找到数据记录。

    故:1、聚簇索引不宜太大,因为,每个普通索引都会存储一份聚簇索引。
    2、适合用递增的数据作为聚簇索引,否则,插入数据的时候,会导致b+树数据分裂,聚簇索引和数据记录发生移动。

    锁差异

    myisam不支持行锁,只支持表锁lock table,在读写操作的时候,都会对数据添加表锁,select的时候,自动获取表级读锁。读和读可以并行,读和写不可以并行,故select没有释放读锁,update、insert、delete这种写操作需要获取写锁,需要等待读锁释放。写锁和写锁互斥,写锁和读锁互斥,所以,update、insert、delete没有释放写锁的时候,select操作需要等待。和java的ReentrantReadWriteLock读写锁类似,但是myisam的写锁优先级高于读锁,就是说,写锁和读锁都在等待获取锁,即使读锁先进入等待队列,写锁还是会先获取锁,因为,myisam认为写操作少,读操作多,写比读重要,故myisam不适合写多读少的场景。

    故:myisam高并发下,效率比较低,不建议使用。

    举个实际的例子:
    test表是myisam引擎。
    一个会话:insert into test values (14, 'abcd', '3' and sleep(90));
    另一个会话:insert into test values (15, 'abcd', '3');会堵塞,直到第一个会话释放表级写锁。
    而如果是innodb就不会。

    innodb支持多种锁,锁的是索引,而不是实际的数据记录,故如果锁不到实际的索引,则会锁住整个表,比如 where id != 10。
    详情看之前的记录:innodb的7种锁 https://www.jianshu.com/p/8c0c9d3b0306

    关于count()
    myisam会直接存储行数,故select count(
    )可以直接读取这个数据,很快,但是如果加上where 条件,则和innodb一样需要遍历所有行数,依然消耗很大。
    innodb则需要遍历所有行数,故消耗很大。

    关于全文索引
    myisam支持全文索引,innodb5.6版本之后InnoDB存储引擎开始支持全文索引,5.7版本之后通过使用ngram插件开始支持中文。
    比如like查询:like %abc%,不走索引,效率很低,然而使用全文索引,仅效率层面上会有所提高。
    但是,因为全文索引占用数据库资源比较多,故,对于模糊搜索类似的请求,还是用外置索引比较好,比如es、solr类似的搜索引擎。

    关于事务
    myisam不支持事务,由于其不支持事务,在系统异常崩溃的时候,有可能会导致文件损坏。
    innodb支持事务,但是事务比较消耗性能。

    关于外键
    myisam不支持外键。innodb支持外键。但是实际使用中,不建议在数据库中使用外键维护数据完整性,占用资源,影响性能,会让数据关系变得极其复杂,不利于数据的处理。而是通过程序来弱控制数据关系。

    相关文章

      网友评论

        本文标题:myisam和innodb的差异

        本文链接:https://www.haomeiwen.com/subject/kzgrnqtx.html