对于存储引擎,例如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
和语句,因为触发器可以更改其值:
表的任何分区列上的触发器意味着由或
不能设置的锁被修剪,因为
触发器可能会在插入行之前更改行的分区列,从而迫使该行进入与其他情况不同的分区。分区列上的
触发器意味着强加的锁或
无法修剪的锁。
UPDATE
BEFORE INSERT
INSERT
REPLACE
BEFORE INSERT
BEFORE UPDATE
UPDATE
INSERT ... ON DUPLICATE KEY UPDATE
受影响的 DDL 语句
CREATE VIEW
不会导致任何锁定。
ALTER
TABLE ... EXCHANGE PARTITION
修剪锁;只有交换表和交换分区被锁定。
ALTER
TABLE ... TRUNCATE PARTITION
修剪锁;只有要清空的分区被锁定。
此外,ALTER TABLE
语句在表级别采用元数据锁。
其他声明
LOCK TABLES
不能修剪分区锁。
CALL
stored_procedure(
支持锁修剪,但
expr
)expr
不支持评估。