好吧,两个引擎之间的锁定原理是不同的。
使用 MyISAM,全表锁定的原因是写入通常应该很快。写入只需要两个操作(锁定表,然后将行写入磁盘)。由于这个原因,MyISAM 的性能确实受磁盘速度的限制。
使用 InnoDB,它变得有点复杂。由于它完全符合 ACID,因此每次写入都需要 4 个步骤(锁定行、写入事务日志、写入行到磁盘、写入事务日志)。请注意,它会写入磁盘 3 次。所以这意味着(在实践中)InnoDB 写入将比 MyISAM 写入花费 3 倍的时间。这是行级锁定的一个原因(事务是另一个)。
但这并不容易。使用 MyISAM,表锁需要一个用于该表的信号量。因此,对内存使用和速度的影响充其量是微不足道的。然而,对于 InnoDB,它需要一个索引和每行一个信号量。它需要一个索引来加速“检查”以查看该行是否已经有锁。现在,如果您同时更新 1 行或 10 行,差别不大。但是,当您谈论数百万行时,差异可能并非微不足道(无论是在内存使用情况还是在速度方面,因为它需要横向锁定要锁定的每一行的锁定“索引”)。
还有一个额外的权衡。由于 InnoDB 符合 ACID,因此如果出现断电(或其他崩溃),您永远不会处于不一致的状态。数据库中没有未提交的事务数据,也没有已提交的事务损坏(如果检测到要修复的内容,它将自动运行事务日志)。使用 MyISAM,写入过程中的断电(或崩溃)会使表处于不一致的状态,您对此无能为力。如果你关心你的数据,InnoDB 会更好。但是,有了良好的二进制日志和备份系统,您应该能够恢复 MyISAM,但这需要一些手动干预......
现在,话虽如此,你关于哪个规模更好的问题真的很难。首先,您的大部分作品都是处理一两行吗?如果是这样,InnoDB 和行级锁定将倾向于更好地扩展。如果您同时执行大量查询更新大量行(数万甚至更多),您会注意到 MyISAM 往往具有更好的性能。
至于您的死锁问题,MySQL 将为您定位并处理它们(但它不会执行其中一个查询,因此您可能需要一些异常处理代码来重试查询或其他内容)。内部系统将防止死锁...
现在,另一个注意事项。既然 MySQL 在一个 db 中支持多个引擎,为什么不把你的数据放到 InnoDB 中,然后做一个 MyISAM 连接表来处理嵌套的集合数据呢?将育儿信息存储在数据表中(通过parent_id
机制)。这样,您的所有数据都在符合 ACID 的数据库中,但是您可以通过使用更快的(用于读取和大量写入)MyISAM 用于嵌套集逻辑来提高速度......