MySQL table partition by month

2020-02-23 08:44发布

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 queries are starting to get slower when i try to fetch events from a large timeframe, and after reading quite a bit on the subject i understand that partitioning the table may boost the performance.

What i want to do is partition the table on a per month basis.

I have only found guides that show how to partition manually each month, is there a way to just tell MySQL to partition by month and it will do that automatically?

If not, what is the command to do it manually considering my partitioned by column is a datetime?

3条回答
家丑人穷心不美
2楼-- · 2020-02-23 09:07

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)));
查看更多
可以哭但决不认输i
3楼-- · 2020-02-23 09:16

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.)

查看更多
欢心
4楼-- · 2020-02-23 09:28

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

查看更多
登录 后发表回答