对于存储引擎,例如MyISAM
在执行 DML 或 DDL 语句时实际执行表级锁,旧版本 MySQL(5.6.5 及更早版本)中影响分区表的语句会对整个表施加锁;也就是说,所有分区都被锁定,直到语句完成。在 MySQL 5.7 中,分区锁修剪在许多情况下消除了不需要的锁,并且大多数读取或更新分区
MyISAM表的语句只会导致受影响的分区被锁定。例如,
SELECT分区
MyISAM表中的 a 仅锁定那些实际包含满足
SELECT语句的
WHERE条件被锁定。
对于使用存储引擎影响分区表的语句,例如InnoDB使用行级锁定并且在分区修剪之前实际上不执行(或不需要执行)锁定,这不是问题。
接下来的几段讨论了分区锁修剪对各种 MySQL 语句对使用表级锁的存储引擎的表的影响。
对 DML 语句的影响
SELECT语句(包括那些包含联合或连接的语句)只锁定那些实际需要读取的分区。这也适用于
SELECT ... PARTITION.
UPDATE修剪锁只针对没有更新分区列的表
。
REPLACE并
INSERT仅锁定那些具有要插入或替换的行的分区。但是,如果
AUTO_INCREMENT为任何分区列生成一个值,则所有分区都将被锁定。
INSERT ...
ON DUPLICATE KEY UPDATE只要没有更新分区列,就会被修剪。
INSERT ...
SELECT只锁定源表中需要读取的那些分区,尽管目标表中的所有分区都被锁定。
分区表上的语句强加的锁LOAD DATA
不能被修剪。
存在BEFORE INSERT或
BEFORE 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不支持评估。