web-dev-qa-db-ja.com

月ごとのMySQLテーブルパーティション

ユーザーのクリックなど、追跡された多くのイベントを格納する巨大なテーブルがあります。

テーブルはすでに数千万に達し、日々大きくなっています。長い時間枠からイベントをフェッチしようとすると、クエリが遅くなり始めています。この件についてかなり読んだ後、テーブルをパーティション分割するとパフォーマンスが向上する可能性があることを理解しています。

私がやりたいのは、月ごとにテーブルを分割することです。

毎月手動でパーティションを作成する方法を示すガイドしか見つかりませんでしたが、MySQLに月ごとにパーティションを作成するように指示する方法はありますか?それは自動的に行われますか?

そうでない場合、列でパーティション化されているのが日時であると見なして、手動で実行するコマンドは何ですか?

11
shaharmor

マニュアルで説明されているように: http://dev.mysql.com/doc/refman/5.6/en/partitioning-overview.html

これは、月の出力をハッシュ分割することで簡単に実現できます。

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

これは月ごとにのみパーティション化され、年ごとにはパーティション化されないことに注意してください。また、この例では6つのパーティション(つまり6か月)しかありません。

また、既存のテーブルをパーティション分割する場合(手動: 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;

クエリは、テーブル全体から実行できます。

SELECT * from ti;

または特定のパーティションから:

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

6つのパーティションを持つ月ごとのHASHingは、1年に2か月が同じパーティションに到達することを意味します。それは何が良いですか?

パーティション分割を気にせず、テーブルにインデックスを付けます。

これらが使用する2つのクエリだけであると仮定します。

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

次に、PRIMARY KEYthe_dateで開始します。

最初のクエリは単にテーブル全体を読み取ります。パーティション化されているかどうかの変更はありません。

2番目のクエリは、同じパーティションにマップされるすべての月ではなく、単一の月が必要であると想定して、次のようにする必要があります。

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

他に質問がある場合は、それらを見てみましょう。

PARTITION BY HASHを使用したことによるパフォーマンスの正当化は見つかりませんでした。)

0
Rick James