在 MySQL 5.6.5 及更早版本中,对于诸如在执行 DML 或 DDL 语句时实际执行表级锁的存储引擎
MyISAM,这种影响分区表的语句会对整个表施加锁;也就是说,所有分区都被锁定,直到语句完成。MySQL 5.6.6 实现
分区锁修剪,在很多情况下消除了不需要的锁。在 MySQL 5.6.6 及更高版本中,大多数读取或更新分区MyISAM表的语句只会导致受影响的分区被锁定。例如,在 MySQL 5.6.6 之前,SELECT来自分区的MyISAMtable 导致整个表被锁定;在 MySQL 5.6.6 及更高版本中,只有那些实际包含满足
SELECT语句
WHERE条件的行的分区才会被锁定。这具有提高分区MyISAM表并发操作的速度和效率的效果。MyISAM当处理具有许多(32 个或更多)分区的表
时,这种改进变得特别明显
。
这种行为变化不会对使用存储引擎影响分区表的语句产生任何影响,例如
InnoDB使用行级锁定并且在分区修剪之前实际上不执行(或不需要执行)锁。
接下来的几段讨论了分区锁修剪对各种 MySQL 语句对使用表级锁的存储引擎的表的影响。
对 DML 语句的影响
SELECT语句(包括那些包含联合或连接的语句)现在只锁定那些实际需要读取的分区。这也适用于
SELECT ... PARTITION.
UPDATE修剪锁只针对没有更新分区列的表
。
REPLACE现在
INSERT只锁定那些有行要插入或替换的分区。但是,如果AUTO_INCREMENT为任何分区列生成一个值,则所有分区都将被锁定。
INSERT ...
ON DUPLICATE KEY UPDATE只要没有更新分区列,就会被修剪。
INSERT ...
SELECT现在只锁定源表中需要读取的那些分区,尽管目标表中的所有分区都已锁定。
INSERT
DELAYED分区表不支持。
分区表上的语句强加的锁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不支持评估。