22.6.4 分区和锁定

对于存储引擎,例如MyISAM 在执行 DML 或 DDL 语句时实际执行表级锁,旧版本 MySQL(5.6.5 及更早版本)中影响分区表的语句会对整个表施加锁;也就是说,所有分区都被锁定,直到语句完成。在 MySQL 5.7 中,分区锁修剪在许多情况下消除了不需要的锁,并且大多数读取或更新分区 MyISAM表的语句只会导致受影响的分区被锁定。例如, SELECT分区 MyISAM表中的 a 仅锁定那些实际包含满足 SELECT语句的 WHERE条件被锁定。

对于使用存储引擎影响分区表的语句,例如InnoDB使用行级锁定并且在分区修剪之前实际上不执行(或不需要执行)锁定,这不是问题。

接下来的几段讨论了分区锁修剪对各种 MySQL 语句对使用表级锁的存储引擎的表的影响。

对 DML 语句的影响

SELECT语句(包括那些包含联合或连接的语句)只锁定那些实际需要读取的分区。这也适用于 SELECT ... PARTITION.

UPDATE修剪锁只针对没有更新分区列的表 。

REPLACEINSERT仅锁定那些具有要插入或替换的行的分区。但是,如果 AUTO_INCREMENT为任何分区列生成一个值,则所有分区都将被锁定。

INSERT ... ON DUPLICATE KEY UPDATE只要没有更新分区列,就会被修剪。

INSERT ... SELECT只锁定源表中需要读取的那些分区,尽管目标表中的所有分区都被锁定。

分区表上的语句强加的锁LOAD DATA 不能被修剪。

存在BEFORE INSERTBEFORE UPDATE使用分区表的任何分区列的触发器意味着 无法删除更新此表的锁INSERT和语句,因为触发器可以更改其值: 表的任何分区列上的触发器意味着由或 不能设置的锁被修剪,因为 触发器可能会在插入行之前更改行的分区列,从而迫使该行进入与其他情况不同的分区。分区列上的 触发器意味着强加的锁或 无法修剪的锁。 UPDATEBEFORE INSERTINSERTREPLACEBEFORE INSERTBEFORE UPDATEUPDATEINSERT ... ON DUPLICATE KEY UPDATE

受影响的 DDL 语句

CREATE VIEW不会导致任何锁定。

ALTER TABLE ... EXCHANGE PARTITION修剪锁;只有交换表和交换分区被锁定。

ALTER TABLE ... TRUNCATE PARTITION修剪锁;只有要清空的分区被锁定。

此外,ALTER TABLE 语句在表级别采用元数据锁。

其他声明

LOCK TABLES不能修剪分区锁。

CALL stored_procedure(expr) 支持锁修剪,但 expr不支持评估。

DOand SET 语句不支持分区锁修剪。