InnoDB表使用行级锁定,因此多个会话和应用程序可以同时读取和写入同一个表,而不会彼此等待或产生不一致的结果。对于此存储引擎,请避免使用该LOCK TABLES语句,因为它不提供任何额外的保护,而是减少了并发性。自动行级锁定使这些表适合于具有最重要数据的最繁忙的数据库,同时由于不需要锁定和解锁表,还简化了应用程序逻辑。因此, InnoDB存储引擎是MySQL中的默认引擎。
MySQL对所有存储引擎都使用表锁定(而不是页面锁定,行锁定或列锁定) InnoDB。锁定操作本身没有太多的开销。但是,由于一次只能有一个会话可以写入表,因此要与其他存储引擎一起获得最佳性能,请主要将它们用于经常查询且很少插入或更新的表。
性能方面的考虑有利于InnoDB
选择是使用表InnoDB还是使用其他存储引擎创建表时 ,请记住表锁定的以下缺点:
表锁定使许多会话可以同时从一个表读取数据,但是如果一个会话要写入一个表,则必须首先获得互斥访问,这意味着它可能必须先等待其他会话才能完成对该表的访问。在更新期间,所有要访问此特定表的其他会话都必须等待,直到更新完成。
在会话等待期间,表锁定会导致问题,因为磁盘已满,会话开始之前需要释放可用空间。在这种情况下,所有要访问问题表的会话也将处于等待状态,直到有更多磁盘空间可用为止。
一个SELECT是需要很长的时间,从更新表的同时,使其他场次出现缓慢或无响应运行防止其他会话声明。当会话正在等待获取表的独占访问权以进行更新时,其他发出SELECT语句的会话 将在其后排队,从而即使对于只读会话也降低了并发性。
锁定性能问题的变通办法
以下各项描述了避免或减少表锁定引起的争用的一些方法:
考虑在安装过程InnoDB中使用CREATE TABLE ... ENGINE=INNODB或ALTER TABLE ... ENGINE=INNODB将现有表用于将表切换到 存储引擎 。有关此存储引擎的更多详细信息,请参见 第15章。
优化SELECT语句以使其运行更快,以便它们在较短的时间内锁定表。您可能必须创建一些汇总表才能执行此操作。
启动mysqld的使用 --low-priority-updates。对于仅使用表级锁(如存储引擎 MyISAM,MEMORY和 MERGE),这给所有的语句更新(修改),比表低优先级 SELECT的语句。在这种情况下,SELECT 前面场景中的第二条语句将在该UPDATE语句之前执行,而不会等待第一条语句 SELECT完成。
要指定应以低优先级完成在特定连接中发布的所有更新,请将low_priority_updates 服务器系统变量设置 为1。
要给特定的INSERT, UPDATE或 DELETE语句降低优先级,请使用LOW_PRIORITY 属性。
要赋予特定SELECT 语句更高的优先级,请使用 HIGH_PRIORITY属性。请参见 第13.2.10节“ SELECT语句”。
在 系统变量的值较低的情况下 启动mysqld, max_write_lock_count以强制MySQL SELECT 在对表进行特定次数的插入之后暂时提高所有等待表的语句的优先级。这允许 READ一定数量的锁之后的 WRITE锁。
如果您在与INSERT结合使用时 遇到问题 SELECT,请考虑切换到MyISAM支持并发SELECT和 INSERT语句的表。(请参见 第8.11.3节“并发插入”。)
如果您在混合SELECT和 DELETE语句方面遇到问题 ,则 LIMIT可以选择 DELETE。请参见 第13.2.2节“ DELETE语句”。
使用SQL_BUFFER_RESULTwith SELECT语句可以帮助缩短表锁定的持续时间。请参见 第13.2.10节“ SELECT语句”。
通过允许对一个表中的列运行查询,而将更新限制在另一个表中的列,将表内容拆分为单独的表可能会有所帮助。
您可以更改锁定代码 mysys/thr_lock.c以使用单个队列。在这种情况下,写锁和读锁将具有相同的优先级,这可能对某些应用程序有所帮