题外话:中华文化博大精深,从学习Java到数据库,都体现了同一个组件的精髓鱼和熊掌不可兼得。自然地,很难在编程中同时实现完美的安全性和效率。这次InnoDB和MyISAM又让我大开眼界了。好吧,话不多说,给大家看代码:测试环境:Mysql5.7.20-log,IDEA2018首先创建两张表:testinnodb,testmyisam,sql如下:1.同时大批量插入数据(百万级),万),小编使用存储过程,代码及测试结果如下:在IDEA上可以运行如下代码:同时插入100W条数据,MyISAM耗时约38s,InnoDB耗时约76分钟和4s,明显可以看出MyISAM在处理速度上优于InnoDB,但是如果在实际项目中使用,由于数据安全(或事物安全)问题,大部分公司还是选择InnoDB,很少有公司使用MyISAM(由于其严格在业务层)控制)。但是MyISAM还是可以被我们用在日志数据分析、实验等环境中。2、看删除、修改、查询方面的对比。其实这个差距并没有插入数据那么夸张,这对于大多数要求东西安全的公司来说是可以接受的。PS:可以使用mysql插件profile来显示最近执行命令的时长。用法如下:mysql默认禁用profiles。您需要启用它以检查命令是否已启用:showvariableslike'%pro%';已开启,所以显示为ON,默认为OFF。打开命令:setprofiling=1;关闭命令:setprofiling=0;查询最近使用命令的时长:showprofiles;根据QueryID查询单个命令的详细信息:showprofileforquery1;根据QueryID查询单个命令的memory、source、cpu等详情:showprofilecpuforquery1;或显示查询1的所有配置文件;测试完毕,再总结一下:1、InnoDB支持事物、外键等高级数据库功能,而MyISAM则不支持。需要注意的是,InnDB的行级锁并不是绝对的。比如mysql在执行不确定范围的sql时,仍然会锁表,比如sql中like的使用。远不止于此,在删除、修改、检查时,随着InnoDB的优化,差距逐渐缩小。3.在行数查询中,InnoDB不保存行数,即在select的时候,扫描全表,MyISAM只需要读取保存的行数即可,这也是查询速度快的一个因素MyISAM的。4.索引,InnoDB会自动创建Auto_Increment类型字段的索引,一般用于应用于主键,即主键索引(只包含该字段),而MyISAM可以与其他创建联合索引领域。此外,MyISAM还支持全文索引(FULLTEXT_INDEX)、压缩索引,InnoDB不支持。备注:MyISAM的索引和数据是分离的,索引被压缩了,所以内存使用率也相应增加了很多。可以加载更多索引,而Innodb与索引和数据紧密绑定。如果没有压缩,Innodb比MyISAM大得多。InnoDB存储引擎与MySQL服务器完全集成。InnoDB存储引擎维护自己的缓冲池,用于在主内存中缓存数据和索引。InnoDB将其表和索引存储在一个表空间中,该表空间可以包含多个文件(或原始磁盘分区)。这不同于MyISAM表,例如,其中每个表都存储在一个单独的文件中。InnoDB表可以是任何大小,即使在文件大小限制为2GB的操作系统上也是如此。5.服务器数据备份。InnoDB必须导出SQL进行备份。LOADTABLEFROMMASTER操作不适用于InnoDB。解决方法是先把InnoDB表改成MyISAM表,导入数据后再改成InnoDB表,但是对于InnoDB使用的额外特性(比如带外键的表)是不适用的。备注:另外,MyISAM对编码错误导致的数据恢复响应迅速。MyISAM的数据是以文件的形式存储的,所以在跨平台的数据传输中会非常方便。备份和恢复时可以独立操作一张表。InnoDB复制数据文件,备份binlog,或者使用mysqldump支持容灾(只需要几分钟)。MyISAM不支持它。数据崩溃基本上很难恢复,所以需要经常进行数据备份。6.锁定支持。**MyISAM只支持表锁。InnoDB支持表锁和行锁。行锁大大提高了并发多用户操作的性能。但是InnoDB的行锁只对WHERE的主键有效,非主键的WHERE会锁住整张表。使用场景建议:1)可靠性要求高或需要事务处理时使用InnoDB。这是必须的。2)表的更新和查询比较频繁,表锁的几率比较高,指定InnoDB数据引擎的创建。相比之下,MyISAM的使用场景:1)做大量的count计算。比如一些日志,调查业务表。2)插入和修改不频繁,查询非常频繁。MySQL允许你在表级别应用数据库引擎,因此你可以只优化需要事务处理的表的性能,而将不需要事务处理的表交给更便携的MyISAM引擎。对于MySQL,灵活性是关键。引擎原理分析MyISAM索引结构:MyISAM索引使用B+树来存储数据,MyISAM索引的指针指向key值的地址,该地址存储数据。B+Tree的数据域存储的内容是实际数据的地址,也就是说它的索引和实际数据是分开的,但是索引是用来指向实际数据的。这个索引就是所谓的非聚集索引master索引如下:辅助索引如下:因此,过程是:MyISAM中的索引检索算法是先根据B+Tree查找索引算法,如果指定的Key存在,取出数据域的值,然后使用数据域Address的值,根据数据域的值读取对应的数据记录。InnoDB引擎的索引结构:也是B+Tree索引结构。Innodb的索引文件本身就是一个数据文件,也就是B+Tree的数据字段存放的是实际的数据,而这个索引就是一个聚簇索引。这个索引的key是数据表的主键,所以InnoDB表数据文件本身就是主索引。InnoDB的辅助索引数据字段也存储的是对应记录主键的值而不是地址,所以用辅助索引查找时,会先根据辅助索引找到主键,再根据主键索引。因此Innodb不建议使用过长的主键,否则辅助索引会变得过大。推荐使用自增字段作为主键,这样B+Tree的每个节点都会依次填充,而不需要频繁的拆分调整,有效提高插入数据的效率。主索引如下:辅助索引如下:在上图中,可以看到叶子节点包含了完整的数据记录。这种类型的索引称为聚簇索引。因为InnoDB的数据文件是按照主键聚合的,所以InnoDB要求表有主键(MyISAM可能没有)。如果没有明确指定,MySQL系统会自动选择一个能够唯一标识数据记录的列作为主键。如果不存在这样的列,MySQL会自动生成一个隐式字段作为InnoDB表的主键。该字段长度为6字节,类型为长整型。而且,与MyISAM索引不同的是,InnoDB的辅助索引数据字段存储的是对应记录的主键值,而不是地址。换句话说,InnoDB的所有二级索引都将主键作为数据字段。因此,流程是:将主键组织成一颗B+树,行数据存放在叶子节点上。如果使用条件“whereid=13”来查找主键,则可以根据B+树的搜索算法找到对应的叶子节点,进而获取行数据。如果对Name列进行条件查找,需要两步:第一步在辅助索引B+树中检索Name,到达其叶子节点,获取对应的主键。第二步,使用主键对主索引B+树种再进行一次B+树检索操作,最终到达叶子节点,得到整行数据。两个索引数据查找过程如下:
