按年分区和按月分区的子分区

时间:2014-05-22 09:20:40

标签: mysql partitioning

我有一个数据库,日期列的数据类型为date。

该表预计每天有10k行。我想在年份范围的表上创建分区,然后在该特定年份的几个月创​​建子分区。

我试过了,

ALTER TABLE nav_master
    PARTITION BY RANGE( YEAR(nav_date) )
    SUBPARTITION BY HASH( MONTH(nav_date) )
    SUBPARTITIONS 12 (
        PARTITION january VALUES LESS THAN (2),
        PARTITION february VALUES LESS THAN (3),
        PARTITION march VALUES LESS THAN (4),
        PARTITION april VALUES LESS THAN (5),
        PARTITION may VALUES LESS THAN (6),
        PARTITION june VALUES LESS THAN (7),
        PARTITION july VALUES LESS THAN (8),
        PARTITION august VALUES LESS THAN (9),
        PARTITION september VALUES LESS THAN (10),
        PARTITION october VALUES LESS THAN (11),
        PARTITION november VALUES LESS THAN (12),
        PARTITION december VALUES LESS THAN (13)
    );

我能够在空表上执行上述查询。但是当我插入或在同一个表中执行上述查询时,我得到了以下错误。

#1526 - Table has no partition for value 2014

无法理解确切的错误是什么。

另请告诉我子分区是否有助于更好地优化表格,或者我应该选择分区?

4 个答案:

答案 0 :(得分:0)

您希望按年份按月组织所有数据,然后这可能更合适:

    PARTITION BY HASH( YEAR(nav_date) )
        SUBPARTITION BY HASH( MONTH(nav_date) )
    ...

答案 1 :(得分:0)

        PARTITION january VALUES LESS THAN (2),
        PARTITION february VALUES LESS THAN (3),
        PARTITION march VALUES LESS THAN (4),
        PARTITION april VALUES LESS THAN (5),
        PARTITION may VALUES LESS THAN (6),
        PARTITION june VALUES LESS THAN (7),
        PARTITION july VALUES LESS THAN (8),
        PARTITION august VALUES LESS THAN (9),
        PARTITION september VALUES LESS THAN (10),
        PARTITION october VALUES LESS THAN (11),
        PARTITION november VALUES LESS THAN (12),
        PARTITION december VALUES LESS THAN (13)

此部分将值与年(nav_date)进行比较,因此值'2014'不适合您声明的任何条件。

由于您无法通过RANGE或LIST进行分区,因此您将无法获得所需的结果。

答案 2 :(得分:0)

你正在使用2层相同的功能,没有什么大的优势。我更愿意使用基于月份(INTERVAL)的分区为1级并尝试在2级上找到其他用于子分区的键,如数据类型(例如事务类型等)。

预计2层基于INTERVAL的分区不会有太大的改进。

答案 3 :(得分:0)

http://phpfiddle.org上运行此代码。您还可以修改代码中的年份范围。

<?php
$sql="ALTER TABLE nav_master PARTITION BY RANGE(YEAR(nav_date))
SUBPARTITION BY HASH(MONTH(nav_date) ) (";
$startYear=2015;
$endYear=2018;
for($y=$startYear;$y<=$endYear;$y++)
{
    $yy=$y+1;
    $sql.=" PARTITION p$y VALUES LESS THAN ($yy)
(
SUBPARTITION p".$y."_dec ,
SUBPARTITION p".$y."_jan ,
SUBPARTITION p".$y."_feb ,
SUBPARTITION p".$y."_mar ,
SUBPARTITION p".$y."_apr ,
SUBPARTITION p".$y."_may ,
SUBPARTITION p".$y."_jun ,
SUBPARTITION p".$y."_jul ,
SUBPARTITION p".$y."_aug ,
SUBPARTITION p".$y."_sep ,
SUBPARTITION p".$y."_oct ,
SUBPARTITION p".$y."_nov )";
    if ($y!=$endYear)
        $sql.=',';
    else
        $sql.=")";
}
echo $sql;
?>

或在查询下手动运行。

ALTER TABLE nav_master PARTITION BY RANGE(YEAR(nav_date))
 SUBPARTITION BY HASH(MONTH(nav_date) )
  (   PARTITION p2016 VALUES LESS THAN (2017) (
            SUBPARTITION dec_2016,
            SUBPARTITION jan_2016,
            SUBPARTITION feb_2016,
            SUBPARTITION mar_2016,
            SUBPARTITION apr_2016,
            SUBPARTITION may_2016,
            SUBPARTITION jun_2016,
            SUBPARTITION jul_2016,
            SUBPARTITION aug_2016,
            SUBPARTITION sep_2016,
            SUBPARTITION oct_2016,
            SUBPARTITION nov_2016
        ),
        PARTITION p2017 VALUES LESS THAN (2018) (
            SUBPARTITION dec_2017,
            SUBPARTITION jan_2017,
            SUBPARTITION feb_2017,
            SUBPARTITION mar_2017,
            SUBPARTITION apr_2017,
            SUBPARTITION may_2017,
            SUBPARTITION jun_2017,
            SUBPARTITION jul_2017,
            SUBPARTITION aug_2017,
            SUBPARTITION sep_2017,
            SUBPARTITION oct_2017,
            SUBPARTITION nov_2017
        )
   );