MYSQL子分区修剪

时间:2011-12-07 22:14:32

标签: mysql database-partitioning

我有一个MYSQL表,包含年份分区和月份子分区。

CREATE TABLE ptable (
   id INT NOT NULL AUTO_INCREMENT, 
   name varchar(100),
   purchased DATETIME NOT NULL,
   PRIMARY KEY (id, purchased)
)

PARTITION BY RANGE( YEAR(purchased) )
SUBPARTITION BY HASH( MONTH(purchased) )
SUBPARTITIONS 12 (
   PARTITION p0 VALUES LESS THAN (2011),
   PARTITION p1 VALUES LESS THAN (2012),
   PARTITION p5 VALUES LESS THAN MAXVALUE
);

我对此表的大多数查询涉及年份或月份。当我尝试按月查询时,它没有正确修剪并扫描给定年份的所有12个子分区。

explain partitions

SELECT *
FROM ptable
WHERE purchased BETWEEN '2011-12-01' AND '2011-12-31';

我的问题是,当我知道年份和月份值时,有一种方法可以告诉MYSQL只查询特定的子分区吗?或者可能有更好的做法。我正在使用MYSQL 5.1。

2 个答案:

答案 0 :(得分:0)

http://dev.mysql.com/doc/refman/5.1/en/partitioning-pruning.html说:

  

当分区表达式使用YEAR()TO_DAYS()函数时,修剪也可以应用于在DATE或DATETIME列上分区的表。

在MySQL 5.5中,他们将TO_SECONDS()添加到仍然非常短的函数列表中,这些函数可以用来进行分区修剪。

因此,您应该能够使用子分区修剪:

SUBPARTITION BY HASH( TO_DAYS(purchased)/30 )

您仍然可以使用12个子分区,您只会发现每个月的数据不会精确地与子分区对齐。但它会尽可能地修剪。

另一种方法是您可以在表格中添加其他列,例如purchased_month TINYINT UNSIGNED,并将MONTH(purchased)值冗余地存储在该列中。然后使用它作为您的子分区键:

SUBPARTITION BY HASH( purchased_month )

答案 1 :(得分:0)

  

从MySQL 5.6.2开始,SELECT支持使用带有分区或子分区列表的PARTITION关键字进行显式分区选择

对于那些使用较新MySQL的人,我们可以使用SELECT * FROM kit.t1 PARTITION (partition_name [, partition_name] ...);从指定的表(子)分区中选择行