InnoDB
表使用行级锁定,以便多个会话和应用程序可以同时从同一表中读取和写入,不会使彼此等待或产生不一致的结果。对于这个存储引擎,避免使用 LOCK TABLES
语句,因为它不提供任何额外的保护,而是减少了并发性。自动行级锁定使这些表适合您最繁忙的数据库中的最重要数据,同时也简化了应用逻辑,因为您不需要锁定和解锁表。因此,InnoDB
存储引擎是 MySQL 的默认设置。
MySQL 对于所有存储引擎(除了 InnoDB
)使用表锁定(而不是页、行或列锁定)。锁定操作本身没有太多开销。但是,因为只有一个会话可以在任何时候写入表,因此对于这些其他存储引擎的最佳性能,使用它们主要用于经常查询但很少插入或更新的表。
在选择是否使用 InnoDB
或其他存储引擎创建表时,请牢记以下表锁定的缺点:
以下项目描述了一些避免或减少锁定争用引起的性能问题的方法:
-
考虑将表切换到
InnoDB
存储引擎,使用CREATE TABLE ... ENGINE=INNODB
在设置时,或者使用ALTER TABLE ... ENGINE=INNODB
对于现有表。请参阅 第 17 章,InnoDB 存储引擎 了解更多关于这个存储引擎的信息。 -
优化
SELECT
语句以便更快地运行,从而减少表锁定的时间。您可能需要创建一些汇总表来实现这一点。 -
使用 mysqld 启动时带有
--low-priority-updates
。对于使用表级锁定的存储引擎(例如MyISAM
、MEMORY
和MERGE
),这将使所有更新(修改)表的语句的优先级低于SELECT
语句。在这种情况下,第二个SELECT
语句将在第一个SELECT
语句完成之前执行,不会等待第一个SELECT
语句完成。 -
要指定在特定连接中所有更新都以低优先级执行,设置
low_priority_updates
服务器系统变量为1。 -
要给特定
SELECT
语句高优先级,使用HIGH_PRIORITY
属性。见第 15.2.13 节,“SELECT 语句”。 -
使用mysqld,将
max_write_lock_count
系统变量设置为低值,以迫使 MySQL 临时提高所有等待表的SELECT
语句的优先级,直到特定数量的写锁定到表中(例如,插入操作)。这允许在一定数量的写锁定后读锁定。 -
如果您遇到混合
SELECT
和DELETE
语句的问题,LIMIT
选项可能有助于DELETE
。见第 15.2.2 节,“DELETE 语句”。 -
使用
SQL_BUFFER_RESULT
与SELECT
语句可以帮助缩短表锁定的持续时间。见第 15.2.13 节,“SELECT 语句”。 -
将表内容拆分到单独的表中可能有助于,使查询可以在一个表的列上运行,而更新被限制在另一个表的列上。
-
您可以更改
mysys/thr_lock.c
中的锁定代码,以使用单个队列。在这种情况下,写锁定和读锁定将具有相同的优先级,这可能会帮助一些应用程序。