一般上下文
我希望能够在插入具有AUTO INCREMENT
主键的非平衡RANGE
分区MySQL表时判断我的插入是否导致MySQL以任何方式与我指定的分区以外的分区进行通信。这对于预算大规模数据加载的未来容量非常有用;有了这种保证,我可以更准确地预测将数据加载到数据库中的性能和硬件资源成本。
我正在使用MySQL 5.6。
具体背景
假设我在 MySQL (5.6( 中有下表:
CREATE TABLE foo (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`data` varchar(6) COLLATE utf8_bin NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=9001 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
/*!12345 PARTITION BY RANGE (id)
(PARTITION cold VALUES LESS THAN (8000) ENGINE = InnoDB,
PARTITION hot VALUES LESS THAN (9000) ENGINE = InnoDB,
PARTITION overflow VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
假设表不是稀疏的:没有删除任何行,所以count(*) = max(id) = 9001
.
问题
如果我执行包含
PARTITION
子句的INSERT INTO foo (data) PARTITION (hot) VALUES ('abc')
或等效的LOAD DATA
语句,是否正在访问hot
所选分区以外的任何分区?如何判断这些 DML 语句正在访问哪些分区?
我尝试过什么
关于分区选择的MySQL文档说:
替换和插入现在仅锁定那些具有行的分区 插入或更换。但是,如果生成了AUTO_INCREMENT值 对于任何分区列,所有分区都将被锁定。
此外,它说:
由 LOAD DATA 语句对分区表施加的锁不能 修剪。
这些语句无助于阐明显式指定分区的DML 查询正在访问哪些分区。
我试过做EXPLAIN PARTITIONS INSERT INTO foo ...
,但输出的partitions
列总是NULL
。
根据文档,
对于插入行的语句,行为的不同之处在于,找不到合适的分区会导致语句失败。对于 INSERT 和 REPLACE 语句都是如此
因此,当您尝试插入与指定分区不匹配的行时,您将收到
错误代码:1748。发现与给定分区集不匹配的行
这包括某些行匹配而某些行不匹配的语句, 因此,您不能使用它来填充"热"并丢弃会进入"溢出"的行(因为整个查询将失败(。
MySQL 5.6 的explain
-otuput 不包含单独的insert
行;partition
的值与您插入的数据的来源有关(例如,如果您使用insert ... select ... partition ...
(,即使您使用values()
(然后您使用"no table",并且相关的分区只是null
(。对于MySQL 5.7 +,有一个"插入"类型,它确实只会列出您指定的分区。