MySQL table partition by month

后端 未结 4 1326
南旧
南旧 2020-12-28 08:53

I have a huge table that stores many tracked events, such as a user click.

The table is already in the 10\'s of millions, and its growing larger everyday. The querie

相关标签:
4条回答
  • 2020-12-28 09:24
    CREATE TABLE `mytable` (
      `post_id` int DEFAULT NULL,
      `viewid` int DEFAULT NULL,
      `user_id` int DEFAULT NULL,
      `post_Date` datetime DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
    PARTITION BY RANGE (extract(year_month from `post_Date`))
    (PARTITION P0 VALUES LESS THAN (202012) ENGINE = InnoDB,
     PARTITION P1 VALUES LESS THAN (202104) ENGINE = InnoDB,
     PARTITION P2 VALUES LESS THAN (202108) ENGINE = InnoDB,
     PARTITION P3 VALUES LESS THAN (202112) ENGINE = InnoDB,
     PARTITION P4 VALUES LESS THAN MAXVALUE ENGINE = InnoDB)
    
    0 讨论(0)
  • 2020-12-28 09:34

    HASHing by month with 6 partitions means that two months a year will land in the same partition. What good is that?

    Don't bother partitioning, index the table.

    Assuming these are the only two queries you use:

    SELECT * from ti;
    SELECT * from ti PARTITION (HASH(MONTH(some_date)));
    

    then start the PRIMARY KEY with the_date.

    The first query simply reads the entire table; no change between partitioned and not.

    The second query, assuming you want a single month, not all the months that map into the same partition, would need to be

    SELECT * FROM ti  WHERE the_date >= '2019-03-01'
                        AND the_date  < '2019-03-01' + INTERVAL 1 MONTH;
    

    If you have other queries, let's see them.

    (I have not found any performance justification for ever using PARTITION BY HASH.)

    0 讨论(0)
  • 2020-12-28 09:43

    As explained by the manual: http://dev.mysql.com/doc/refman/5.6/en/partitioning-overview.html

    This is easily possible by hash partitioning of the month output.

    CREATE TABLE ti (id INT, amount DECIMAL(7,2), tr_date DATE)
        ENGINE=INNODB
        PARTITION BY HASH( MONTH(tr_date) )
        PARTITIONS 6;
    

    Do note that this only partitions by month and not by year, also there are only 6 partitions (so 6 monhts) in this example.

    And for partitioning an existing table (manual: https://dev.mysql.com/doc/refman/5.7/en/alter-table-partition-operations.html):

    ALTER TABLE ti
        PARTITION BY HASH( MONTH(tr_date) )
        PARTITIONS 6;
    

    Querying can be done both from the entire table:

    SELECT * from ti;
    

    Or from specific partitions:

    SELECT * from ti PARTITION (HASH(MONTH(some_date)));
    
    0 讨论(0)
  • 2020-12-28 09:43

    Use TokuDb which has an access time independent of the table size.

    0 讨论(0)
提交回复
热议问题