gpt4 book ai didi

mysql - MySQL RANGE COLUMNS 分区是如何工作的

转载 作者:行者123 更新时间:2023-11-29 12:58:59 25 4
gpt4 key购买 nike

我准备了一个小测试表来问这个问题:

CREATE TABLE `part_two_cols` (
`period_type_id` int(11) unsigned NOT NULL,
`geolocation_id` tinyint(4) unsigned NOT NULL,
m1 int default 0,
m2 int default 0,
m3 int default 0,
PRIMARY KEY (`period_type_id`,`geolocation_id`),
KEY `fk_data_basic_group_id` (`geolocation_id`),
KEY `fk_data_basic_period_type_id` (`period_type_id`)
);

我想要一个双列分区键(与主键中的列相同)。这些列中的每一列都是一个枚举,可以有 3 个不同的值:1、2、3。所以所有可能的值如下:

INSERT INTO `part_two_cols` (period_type_id, geolocation_id)
VALUES (1,1), (1,2), (1,3), (2,1), (2,2), (2,3), (3,1), (3,2), (3,3);

现在我有 9 条记录。我想准备这样的分区,每个记录都进入单独的分区。我一直在尝试以下方法:

ALTER TABLE `part_two_cols`
PARTITION BY RANGE COLUMNS(period_type_id, geolocation_id) (
PARTITION p0 VALUES LESS THAN (2, 2),
PARTITION p1 VALUES LESS THAN (2, 3),
PARTITION p2 VALUES LESS THAN (2, 4),
PARTITION p3 VALUES LESS THAN (3, 2),
PARTITION p4 VALUES LESS THAN (3, 3),
PARTITION p5 VALUES LESS THAN (3, 4),
PARTITION p6 VALUES LESS THAN (4, 2),
PARTITION p7 VALUES LESS THAN (4, 3),
PARTITION p8 VALUES LESS THAN (4, 4),
PARTITION p9 VALUES LESS THAN (MAXVALUE, MAXVALUE)
);

我失败了,因为在测试 EXPLAIN PARTITIONS 时,结果不是我所期望的:

EXPLAIN PARTITIONS SELECT * FROM `part_two_cols` WHERE period_type_id=1|2|3 AND geolocation_id = 1|2|3;

我得到的结果存储在下表中:

 pt | geo | part
----+-----+------
1 | 1 | p0
1 | 2 | p0
1 | 3 | p0
2 | 1 | p0
2 | 2 | p1
2 | 3 | p2
3 | 1 | p3
3 | 2 | p4
3 | 3 | p5

我想知道为什么所有 pt=1 记录都落入分区 p0 - 即 (1,1)、(1,2) 和 (1,3)?我对单列 RANGE COLUMNS 进行了检查,发现 LESS THAN 实际上是 LESS(而不是小于或等于,这是我要分析的第一个想法)。

问题是:如何更改上面的代码以使每个记录落入一个单独的分区。以及解释是什么。

最佳答案

这个解决方案非常不直观,至少对我来说是这样。事实证明,当 MySQL 将记录插入分区表时,它不会比较所有列。它比较第一列,如果满足条件,则发生插入。如果不满意,它会检查第二列,依此类推。这就是为什么 (1,1) 以及 (1,2)、(1,3) 和 (2,1) 都落入 p0 中。这是因为(1,1)、(1,2)和(1,3)只有12相比,已经满足了,所以插入了。对于 (2,1),22 进行比较,但尚未满足,因此它检查第二列,1 <2 并且第二列满足条件。所以第四条记录仍然属于p0。第五条记录 (2,2) 与 2 相比有 2,尚未满足。比较第二列,2 <2。还没有满足,但是已经没有剩下的列了,所以根本不满足,所以不是p0。但对于 p1 来说是满意的(比较的第二列:2 <3)。

答案 - 如何使每个记录落入单独的分区 - 如下:

ALTER TABLE `part_two_cols`
PARTITION BY RANGE COLUMNS(period_type_id, geolocation_id) (
PARTITION p0 VALUES LESS THAN (1, 2),
PARTITION p1 VALUES LESS THAN (1, 3),
PARTITION p2 VALUES LESS THAN (2, 1),
PARTITION p3 VALUES LESS THAN (2, 2),
PARTITION p4 VALUES LESS THAN (2, 3),
PARTITION p5 VALUES LESS THAN (2, 4),
PARTITION p6 VALUES LESS THAN (3, 2),
PARTITION p7 VALUES LESS THAN (3, 3),
PARTITION p8 VALUES LESS THAN (3, 4),
PARTITION p9 VALUES LESS THAN (MAXVALUE, MAXVALUE)
);

这在某种程度上是合乎逻辑的,但棘手的是我期望一次比较所有列。而MySQL则尽可能少进行比较。

关于mysql - MySQL RANGE COLUMNS 分区是如何工作的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23611350/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com