首页 > 解决方案 > Mysql8按月分区,分区修剪不起作用

问题描述

我有一个按月分区的大表

CREATE TABLE `log` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `logdate` date NOT NULL,
 ...
,
  PRIMARY KEY (`id`,`logdate`)
) PARTITION BY RANGE (month(`logdate`))
(PARTITION part0 VALUES LESS THAN (2),
 PARTITION part1 VALUES LESS THAN (3),
 PARTITION part2 VALUES LESS THAN (4),
 PARTITION part3 VALUES LESS THAN (5),
 PARTITION part4 VALUES LESS THAN (6),
 PARTITION part5 VALUES LESS THAN (7),
 PARTITION part6 VALUES LESS THAN (8),
 PARTITION part7 VALUES LESS THAN (9),
 PARTITION part8 VALUES LESS THAN (10),
 PARTITION part9 VALUES LESS THAN (11),
 PARTITION part10 VALUES LESS THAN (12),
 PARTITION part11 VALUES LESS THAN MAXVALUE);

我已经插入了 3 个月的数据,可以看到这些行已放入各自的分区中。

当我查询指定分区时,返回正确的数据并explain显示它是从正确的分区中选择的

select logdate, sum(total) from log partition(part10) 
                where logdate between '2020-11-01' and '2020-11-30' group by 1 order by 1 desc;

但是,当不指定分区时,不会发生以下分区修剪。

select logdate, sum(total) from log 
                where logdate between '2020-11-01' and '2020-11-30' group by 1 order by 1 desc;


select logdate, sum(total) from log 
                where month(logdate) = 11 group by 1 order by 1 desc;

根据 mysql-8 文档https://dev.mysql.com/doc/refman/8.0/en/partitioning-range.html

基于时间间隔的分区方案。如果您希望在 MySQL 8.0 中实现基于范围或时间间隔的分区方案,您有两种选择:

  1. 按 RANGE 对表进行分区,对于分区表达式,使用对 DATE、TIME 或 DATETIME 列进行操作并返回整数值的函数 - 如我的代码中所示
  1. 使用 DATE 或 DATETIME 列作为分区列,按 RANGE COLUMNS 对表进行分区。

我错过了什么?

标签: mysqldatabase-partitioning

解决方案


推荐阅读