在 MySQL 5.6.5 及更早版本中,对于诸如在执行 DML 或 DDL 语句时实际执行表级锁的存储引擎
MyISAM
,这种影响分区表的语句会对整个表施加锁;也就是说,所有分区都被锁定,直到语句完成。MySQL 5.6.6 实现
分区锁修剪,在很多情况下消除了不需要的锁。在 MySQL 5.6.6 及更高版本中,大多数读取或更新分区MyISAM
表的语句只会导致受影响的分区被锁定。例如,在 MySQL 5.6.6 之前,SELECT
来自分区的MyISAM
table 导致整个表被锁定;在 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
和语句,因为触发器可以更改其值:
表的任何分区列上的触发器意味着由或
不能设置的锁被修剪,因为
触发器可能会在插入行之前更改行的分区列,从而迫使该行进入与其他情况不同的分区。分区列上的
触发器意味着强加的锁或
无法修剪的锁。
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
不支持评估。