表锁是否规模?/对于嵌套集,行锁会更有效吗?

Jer*_*lix 1 mysql myisam innodb

我正在使用嵌套集将层次数据存储在MyISAM表中; 该表由每个用户的几个分层集组成.每个用户将是唯一一个写入其各自树的用户,但其他用户可以从中读取.节点删除/插入要求同一树中的其他行的lft和rgt值更新,可能有数百行.

为了做到这一点,我需要获得一个表写锁,更新树中的其他节点,删除/插入行并解锁表.

我想知道的是 - 表锁可以扩展到数百个并发用户吗?成千上万的?

在这种情况下,InnoDB的行锁会更有效吗?(锁定几百行,主要仅供用户自己使用)

如果我要使用行锁,我是否需要添加显式逻辑来处理死锁错误?

irc*_*ell 5

那么,锁定的理念在两个引擎之间是不同的.

使用MyISAM,全表锁定的原因是写入通常应该很快.写入只需要两个操作(锁定表,然后将行写入磁盘).由于这个原因,MyISAM性能实际上受磁盘速度的限制.

使用InnoDB,它会变得更复杂一些.由于它完全符合ACID,因此每次写入需要4个步骤(锁定行,写入事务日志,将行写入dis,写入事务日志).请注意,它会三次写入磁盘.这意味着(在实践中)InnoDB写入将比MyISAM写入花费3倍.这是行级别锁定的一个原因(事务是另一个).

但这并不容易.使用MyISAM,表锁需要该表的一个信号量.因此,对内存使用和速度的影响充其量是微不足道的.但是,对于InnoDB,它需要一个索引和每行一个信号量.它需要一个索引来加速"检查"以查看是否已经锁定了该行.现在,如果您同时更新一行或十行,则没有什么区别.但是,当你谈论数百万行时,差异可能是非平凡的(在内存使用和速度方面,因为它需要横向锁定每个要锁定的"索引").

还有一个额外的权衡.由于InnoDB符合ACID标准,如果出现断电(或其他崩溃),您永远不会处于不一致状态.数据库中没有未提交的事务数据,并且没有已提交的事务已损坏(如果它检测到要修复的事件,它将自动运行事务日志).使用MyISAM,写入期间的断电(或崩溃)可能会使表处于不一致状态,并且您无法对其进行任何操作.如果你关心你的数据,InnoDB会更好.但是,有了良好的二进制日志和备份系统,你应该能够恢复MyISAM,但它需要一些人工干预......

现在,有了这个说,你的哪个尺度更好的问题真的很难.首先,你的大多数写作是处理一行还是两行?如果是这样,InnoDB和Row级锁定将更容易扩展.如果你做了很多同时更新大量行(数万及以上)的查询,你会发现MyISAM往往会有更好的性能.

至于你的死锁问题,MySQL将为你找到并处理它们(但它不会执行其中一个查询,因此你可能需要一些异常处理代码来重试查询或其他东西).内部系统将防止僵局......

现在,另一个说明.由于MySQL支持db中的多个引擎,为什么不将数据放入InnoDB,然后创建一个MyISAM连接表来处理嵌套的set数据?将父母信息存储在数据表中(通过parent_id机制).这样,您的所有数据都在符合ACID标准的数据库中,但您可以通过使用更快(对于读取和大写入)MyISAM来嵌套集合逻辑来提高速度...