我创建了一个表,如下所示:
CREATE TABLE employees (
id INT NOT NULL,
fname VARCHAR(30),
lname VARCHAR(30),
hired datetime NOT NULL DEFAULT '2000-01-01')
PARTITION BY RANGE ( Month(hired) ) (
PARTITION p1 VALUES LESS THAN (2),
PARTITION p2 VALUES LESS THAN (3),
PARTITION p3 VALUES LESS THAN (4),
PARTITION p4 VALUES LESS THAN (5),
PARTITION p5 VALUES LESS THAN (6),
PARTITION p6 VALUES LESS THAN (7),
PARTITION p7 VALUES LESS THAN (8),
PARTITION p8 VALUES LESS THAN (9),
PARTITION p9 VALUES LESS THAN (10),
PARTITION p10 VALUES LESS THAN (11),
PARTITION p11 VALUES LESS THAN (12),
PARTITION p12 VALUES LESS THAN maxvalue
);
正如您在上面看到的,按月分区已经完成。
接下来,我向表中添加一些记录。
插入记录后,我查询表以验证它是否从预期分区获取数据。
当我给出以下查询时,
EXPLAIN PARTITIONS SELECT COUNT(*)
FROM employees
WHERE hired BETWEEN'2015-01-01' AND '2015-03-01';
理想情况下,它必须扫描分区 p1、p2 和 p3。 但解释结果显示正在扫描所有分区。
我将分区从按月改为按年略有更改,如下所示:
ALTER TABLE employees partition BY range(Year(hired))
PARTITION p1 VALUES LESS THAN (2001),
PARTITION p2 VALUES LESS THAN (2005),
PARTITION p3 VALUES LESS THAN (2010),
PARTITION p4 VALUES LESS THAN (2015),
PARTITION p5 VALUES LESS THAN MAXVALUE);
现在我像以前一样查询:
EXPLAIN PARTITIONS SELECT COUNT(*)
FROM employees
WHERE hired BETWEEN '2015-01-01' and '2015-03-01';
结果显示它仅从分区 p5 获取数据。
我不知道为什么它适用于按年分区而不是按月分区。白天也观察到同样的问题。
请帮助我了解为什么 MySQL 会出现这样的行为。
最佳答案
您还发现了另一种情况,其中PARTITIONing
没有用。
BETWEEN '2015-01-01' and '2015-03-01'; -- could have been optimized
BETWEEN '2015-01-01' and '2016-03-01'; -- must touch all partitions
分区修剪代码太愚蠢,无法区分两者之间的区别。
即使修剪按预期工作,查询也不会比使用 INDEX(hired)
的非分区表快。您有任何可能会更好的查询吗?
关于Mysql - 按月分区扫描所有分区而不是一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36791662/