このブログ投稿では、MySQLの最も広く使用されている機能の1つであるパーティションについて説明します。
パーティショニングとは何ですか?
MySQLでは、パーティショニングはデータベース設計手法であり、データベースはデータを複数のテーブルに分割しますが、SQLレイヤーによってデータを単一のテーブルとして扱います。簡単に言うと、テーブルをパーティション化するときは、テーブルを複数のサブテーブルに分割します。パーティション化が使用されるのは、データの一部にのみアクセスできるようにすることで特定のクエリのパフォーマンスが向上し、高速化されるためです。データとインデックスを多数のディスクボリュームに分割できるため、I/O操作も改善できます。
パーティション化には、水平方向と垂直方向の2種類があります。水平分割では、さまざまな行をさまざまなテーブルに配置します。一方、垂直分割では、列の数が少ないテーブルを作成し、追加のテーブルを使用して残りの列を格納します。
- SELECTクエリを使用すると、パーティショニングレイヤーがパーティションを開いてロックし、クエリオプティマイザーがパーティションのいずれかをプルーニングできるかどうかを判断し、パーティショニングレイヤーがハンドラーAPI呼び出しを処理するストレージエンジンに転送します。パーティション。
- INSERTクエリを使用すると、パーティショニングレイヤーがパーティションを開いてロックし、行が属するパーティションを決定してから、そのパーティションに行を転送します。
- DELETEクエリを使用すると、パーティションレイヤーが開いてパーティションをロックし、行が含まれているパーティションを特定して、そのパーティションから行を削除します。
- UPDATEクエリが使用されると、パーティショニングレイヤーがパーティションを開いてロックし、どのパーティションに行が含まれているかを判断し、行をフェッチして変更し、新しい行を含める必要があるパーティションを決定して、行を転送します挿入要求を使用して新しいパーティションに転送し、削除要求を元のパーティションに転送します。
いつパーティショニングを使用する必要がありますか?
一般に、パーティショニングは次の場合に役立ちます。
- テーブルには履歴データが含まれており、新しいデータが最新のパーティションに追加されます。
上記の1つ以上のシナリオで状況が説明されている場合は、パーティション分割が役立つ場合があります。ただし、データをパーティション化する前に、MySQLパーティションには独自の制限があることに注意してください。
- パーティション式では、ストアドプロシージャ、ストアド関数、ユーザー定義関数(UDF)、またはプラグインの使用は許可されておらず、SQL関数のサポートは制限されています。宣言または保存された変数を使用することもできません。
- パーティション化されたテーブルには、外部キーを含めたり、外部キーから参照したりすることはできません。
- テーブルごとに1,024パーティションの制限があります(MariaDB 10.0.4以降、テーブルには最大8,192パーティションを含めることができます)。
- テーブルは、ストレージエンジンがパーティショニングをサポートしている場合にのみパーティショニングできます。
- FullTEXTインデックスはサポートされていません
上記のオプションは、パーティショニングがオプションであるかどうかを判断するのに役立ちます。
パーティションを使用する場合は、選択できるパーティションの種類がいくつかあることに注意してください。以下で簡単にオプションについて説明し、次にそれらについて詳しく説明します。
- RANGEによるパーティション化は、特定の範囲内にある列の値に基づいて行をパーティション化するのに役立ちます。
- LISTによるパーティション化は、特定のリストの列値のメンバーシップに基づいて行をパーティション化するのに役立ちます。
- HASHによるパーティション化は、ユーザー定義の式によって返される値に基づいて行をパーティション化するのに役立ちます。
- KEYによるパーティション化は、MySQLが提供するハッシュ関数に基づいて行をパーティション化するのに役立ちます。
RANGEによるパーティション化は、MySQLテーブルをパーティション化する最も一般的な形式の1つです。テーブルをRANGEでパーティション化する場合、各パーティションに特定の範囲内の特定の数の行が含まれるようにテーブルをパーティション化します。パーティションを定義するには、その名前を定義してから、保持する必要のある値を指定します。テーブルを範囲でパーティション化するには、PARTITIONBYRANGEステートメントを追加します。たとえば、パーティションにp0という名前を付け、5未満のすべての値を保持するようにする場合は、クエリにPARTITION p0 VALUES LESS THAN(5)が含まれていることを確認する必要があります。パーティションテーブルの例を次に示します。
CREATE TABLE sample_table (
id INT(255) NOT NULL AUTO_INCREMENT PRIMARY KEY,
column_name VARCHAR(255) NOT NULL DEFAULT ‘’
...
) PARTITION BY RANGE (column_name) (
PARTITION p0 VALUES LESS THAN (5),
PARTITION p1 VALUES LESS THAN (10),
PARTITION p2 VALUES LESS THAN (15),
PARTITION p3 VALUES LESS THAN (20),
...
);
次のように、特定の範囲に含まれないすべての値を保持するパーティションを定義することもできます。
PARTITION p5 VALUES LESS THAN MAXVALUE
上記のパーティションはp5という名前で、他のパーティションにはないすべての値を保持します-MAXVALUEは、可能な最大値より常に高い値を表します。次のようにパーティションを定義して関数を使用することもできます:
PARTITION BY RANGE (YEAR(date)) (
PARTITION p0 VALUES LESS THAN (2000),
PARTITION p1 VALUES LESS THAN (2010),
PARTITION p2 VALUES LESS THAN (2020),
PARTITION p3 VALUES LESS THAN MAXVALUE
);
この場合、2000未満のすべての値はパーティションp0に格納され、2010未満のすべての値はパーティションp1に格納され、2020未満のすべての値はに格納されます。パーティションp2と、これらの範囲のいずれにも該当しないすべての値は、パーティションp3に格納されます。
MySQLテーブルをLISTでパーティション化することは、RANGEでパーティション化することに似ています-LISTでテーブルをパーティション化する主な違いは、テーブルをLISTでパーティション化する場合、各パーティションは列値のメンバーシップに基づいて定義および選択されることです。値の範囲ではなく、値リストのセットで。 LISTによるパーティション分割は、たとえば、複数の小さなデータセット(たとえば、リージョン)に分割できるデータがあることがわかっている場合に役立ちます。町の中心部に1つ、北に2つ、東に3つ、西に4つ、合計4つのフランチャイズがある店舗があるとします。特定のフランチャイズに属するデータがそのフランチャイズ専用のパーティションに保存されるように、テーブルをパーティション化できます。
PARTITION BY LIST(store) (
PARTITION central VALUES IN (1,3,5),
PARTITION north VALUES IN (2,4,7),
PARTITION east VALUES IN (8,9),
PARTITION west VALUES IN (10,11)
);
HASHによる分割
MySQLテーブルをHASHでパーティション化することは、パーティション間でデータが均等に分散されるようにする方法です。 HASHでテーブルをパーティション分割する場合は、データを分割する必要のあるパーティションの数を指定するだけで済みます。残りはMySQLで処理されます。次のステートメントをCREATETABLEに追加することにより、HASHによるパーティショニングを使用できます。
PARTITION BY HASH(id)
PARTITIONS 5;
5を、データを分割する必要のあるパーティションの数を指定する番号に置き換えます。デフォルトの番号は1です。
MySQLは、LINEAR HASHによるパーティショニングもサポートしています。線形ハッシュは線形2乗アルゴリズムを利用しているため、線形ハッシュは通常のハッシュとは異なります。テーブルをLINEARHASHで分割するには、PARTITIONBYHASHをPARTITIONBYLINEARHASHに置き換えます。
KEYによるパーティション分割
MySQLテーブルをKEYでパーティション化することは、MySQLテーブルをHASHでパーティション化することに似ています。この場合、キーパーティション化のハッシュ関数はMySQLサーバーによって提供されます。パーティショニングキーとして使用される列は、テーブル全体の主キーを構成するか、少なくともテーブルの主キーの一部である必要があります。パーティション化キーとして列名が指定されていない場合は、主キーが使用されます。主キーがなく、一意のキーがある場合は、代わりに一意のキーが使用されます。たとえば、最初のステートメントでパーティショニングキーが指定されていなくても、次のステートメントは両方とも有効です。
CREATE TABLE demo_table (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL DEFAULT ''
)
PARTITION BY KEY()
PARTITIONS 2;
CREATE TABLE demo_table (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
)
PARTITION BY KEY(id)
PARTITIONS 5;
要約すると、データが多い場合、テーブルが大きすぎてメモリに収まらない場合、またはテーブルに履歴データが含まれている場合は、パーティションが役立ちます。パーティションは、テーブルの内容をさまざまなストレージメディアに分散する必要があると考えている場合や、個々のパーティションを削除または復元するオプションが必要な場合にも役立ちます。
ただし、MySQLのパーティションには独自の欠点があることに注意してください。パーティション分割の主な欠点の1つは、テーブルが大きくなることです。スペースを犠牲にすることなく速度を上げることはできません。非常に大量のデータセットがある場合、これはかなり大きな問題になる可能性があります。