どのように見えますか?
CREATE TABLE orders_range (
customer_surname VARCHAR(30),
store_id INT,
salesperson_id INT,
order_date DATE,
note VARCHAR(500)
) ENGINE = MYISAM
PARTITION BY RANGE( YEAR(order_date) ) (
PARTITION p_old VALUES LESS THAN(2008),
PARTITION p_2008 VALUES LESS THAN(2009),
PARTITION p_2009 VALUES LESS THAN(MAXVALUE)
);
何が得られますか? 最初の「テーブル」は、2008年までの「アーカイブ」期間のデータを保存し、2番目は2008年、「3番目」はそれ以外のすべてを保存します。
最もおいしいのは、リクエストを書き換えたり最適化する必要がないことです。
select * from orders_range where order_date='2009-08-01';
そして、これは何が起こるかです:
mysql> explain partitions select * from orders_range3 where order_date='2008-08-01';
+----+-------------+---------------+------------+--------+---------------+------+---------+------+------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------+------------+--------+---------------+------+---------+------+------+-------+
| 1 | SIMPLE | orders_range3 | p_2008 | system | NULL | NULL | NULL | NULL | 1 | |
+----+-------------+---------------+------------+--------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)
このリクエストが実行されると、作業は排他的に「サブテーブル」p_2008で実行されることがわかります。
さらに、すべてのパーティションのすべてのデータに影響するクエリの場合でも高速化が実現されます。この場合、テーブルの最初の「処理」が最初に少なくなり、データが結合されて最終計算が実行されるためです。 したがって、この場合、「最初の」段階だけがはるかに速く発生します。
他にどんな利点がありますか?
主な利点は、「操作」データ(つまり、最も頻繁に選択される最後のデータ)を持つパーティションのサイズが最小であり、その結果、常にRAMにあるという事実です。
常に書き込まれているログテーブルがあり、ハードディスクが間に合わず、宗教がRAIDを許可しない場合、ハッシュ関数によるパーティションを構成し、使用可能なハードドライブごとに1つのパーティションを指定できます。 この場合、新しいデータはすべてのハードドライブに均等に書き込まれます。
mySQLでデータを「分割」する方法は何ですか?
1.範囲
値の範囲ごと
範囲ごとのパーティション(store_id)(
パーティションp0の値が(10)未満、
パーティションp1の値が(20)未満、
パーティションp3の値が(30)未満
);
2.リスト
値の正確なリストによる
リストによるパーティション(store_id)(
PARTITION pNorth VALUES IN(3,5,6,9,17)、
パーティションピーストバリューイン(1,2,10,11,19,20)
)
なぜですか? パーティション化は、サンプル最適化の考慮事項(より一般的)またはレコード最適化の考慮事項(あまり頻繁ではありません)に基づいて必要です。 したがって、理想的なオプションは、すべてのサンプルの90%が同じパーティション内で発生するように、テーブルを可能な最大数のパーティションに分割する場合です。 また、複雑なサンプリングロジック(たとえば、IDが異なる都市の北部に位置するオブジェクト)がある場合、それらを強制的にリストすることが理にかなっている場合があります。
3.ハッシュ
ハッシュによるパーティション(store_id)
パーティション4;
パーティション化を制御することはできません;ハッシュを作成するフィールドと、作成する「サブテーブル」の数を指定するだけです。 なんで? 指定されたフィールドではるかに高速な選択が行われます。 場合によっては、「均一な広がり」を実現し、データ記録を高速化できます。
4.キー
HASHとほぼ同じですが、より論理的です-キーによって。
キーによるパーティション(s1)
パーティション10;
つまり 指定されたキーフィールドによるサンプリングは、可能な限り効率的です。
ただし、ここでパーティション分割の方法も決定する必要があります。 ログインが他のすべてのデータを選択する必要がある唯一の識別子である場合、訪問者のカウンターに適しています。
どうして?
垂直分割はありません。 これは、異なる列(フィールド)が異なる「サブテーブル」にある場合です。 これは便利な場合があるため、それほど透明ではない場合でも、自分でこれを実現できます。主キーに従ってリンクしてテーブルを2つに分割します。 本当に美しさが必要な場合は、たとえば、コードの古い部分を書き換えないように、ビューをさらに作成できます。
これはなぜですか? たとえば、主に数字と日付があるテーブルには、コメント用に1つのVARCHARフィールド(255)があります。これは、他のフィールドよりも桁違いに使用されます。 別のテーブルに配置すると、固定の行サイズが取得されます(mySQLは、データファイル内のインデックスによって目的の行の位置を正確に計算できます)。 テーブルは、緊急の場合の障害に対する回復力が高まります(再び、固定行サイズのため)。 さて、テーブルサイズ自体は大幅に減少します。
そして、記事の終わりに、より「実際の」テーブルのパーティション分割の例を示します-毎月。 LIST / RANGEは整数値のみを受け入れるため、少し凝ったものにする必要があります。
PARTITION BY RANGE(TO_DAYS(order_date))(
PARTITION y2009m1 VALUES LESS THAN(TO_DAYS( '2009-02-01'))、
PARTITION y2009m2 VALUES LESS THAN(TO_DAYS( '2009-03-01'))、
PARTITION y2009m3 VALUES LESS THAN(TO_DAYS( '2009-04-01'))
);
PS:mysqlでは、常に少し「手に負えない」ものを取得する必要があるため、それに飽きることはありません。また、私たちは仕事なしで放置されることはありません:)