このセクションでは、MySQL 8.0 のパーティショニングの概念について説明します。
パーティショニングの制約および機能制限については、セクション24.6「パーティショニングの制約と制限」を参照してください。
SQL 標準では、データ保存の物理的な仕様に関するガイダンスはあまり提供されていません。 SQL 言語自体が、それが動作するスキーマ、テーブル、行、またはカラムの基盤となるデータ構造やメディアと独立して動作するように意図されています。 それにもかかわらず、ほとんどの高度なデータベース管理システムでは、ファイルシステム、ハードウェア、またはその両方について、特定のデータを格納するために使用される物理的な場所を判別する方法が開発されてきました。 MySQL では、InnoDB
ストレージエンジンが長い間テーブルスペースの概念をサポートしており (セクション15.6.3「テーブルスペース」 を参照)、パーティション分割を導入する前でも、異なるデータベースを格納するために異なる物理ディレクトリを使用するように MySQL Server を構成できます (この方法については セクション8.12.2「シンボリックリンクの使用」 を参照)。
パーティショニングはこの認識をさらに一歩進めて、必要に応じて多くの部分を設定できるルールに従って、個々のテーブルの部分をファイルシステムに配分できるようにしています。 それにより、テーブルの異なる部分が別個のテーブルとして別個の場所に格納されます。 データを分割するためにユーザーが選択するルールはパーティショニング関数と呼ばれ、MySQL では法、範囲セットまたは値リストに対する単純な照合、内部ハッシュ関数、または線形ハッシュ関数が使用されます。 関数は、ユーザーが指定したパーティショニングタイプに従って選択され、ユーザーが指定した式の値をパラメータとして取ります。 この式には、使用されるパーティショニングのタイプに応じて、カラム値、1 つ以上のカラム値を操作する関数、または 1 つ以上のカラム値のセットを指定できます。
RANGE
、LIST
、および [LINEAR
] HASH
パーティショニングの場合、パーティショニングカラムの値はパーティショニング関数に渡され、特定のレコードを格納すべきパーティションの番号を表す整数値が返されます。 この関数は非定数および非ランダムである必要があります。 クエリーを含めることはできませんが、式が NULL
または次のような整数 intval
を返すかぎり、MySQL で有効な SQL 式を使用できます。
-MAXVALUE <= intval <= MAXVALUE
(MAXVALUE
は対象となる整数型の上限を表すために使用されます。-MAXVALUE
は下限を表します。)
[LINEAR
] KEY
、RANGE COLUMNS
、および LIST COLUMNS
パーティショニングの場合、パーティショニング式は 1 つ以上のカラムのリストから構成されます。
[LINEAR
] KEY
パーティショニングの場合、パーティショニング関数は MySQL によって提供されます。
許可されるパーティショニングカラムタイプおよびパーティショニング関数については、セクション24.2「パーティショニングタイプ」、およびパーティショニング構文の説明および追加例を示しているセクション13.1.20「CREATE TABLE ステートメント」を参照してください。 パーティショニング関数の制約については、セクション24.6.3「関数に関連するパーティショニング制限」を参照してください。
これは「水平パーティショニング」と呼ばれます。つまり、テーブル内の異なる行を異なる物理パーティションに割り当てることができます。 MySQL 8.0 では、テーブルの異なるカラムが異なる物理パーティションに割り当てられる垂直パーティション化はサポートされていません。 現時点では、MySQL に垂直パーティション化を導入する計画はありません。
パーティション化されたテーブルを作成するには、それらをサポートするストレージエンジンを使用する必要があります。 MySQL 8.0 では、同じパーティション化されたテーブルのすべてのパーティションが同じストレージエンジンを使用する必要があります。 ただし、同じ MySQL サーバーまたは同じデータベース上の異なるパーティション化されたテーブルに、異なるストレージエンジンを使用することはできます。
MySQL 8.0 では、パーティション分割をサポートするストレージエンジンは InnoDB
と NDB
だけです。 パーティション分割は、それをサポートしていないストレージエンジンでは使用できません。これには、MyISAM
, MERGE
, CSV
および FEDERATED
ストレージエンジンが含まれます。
KEY
または LINEAR KEY
によるパーティショニングは NDB
で使用できますが、ほかのタイプのユーザー定義パーティショニングはこのストレージエンジンを使用するテーブルでサポートされません。 また、ユーザー定義パーティショニングを使用する NDB
テーブルには明示的な主キーが必要であり、テーブルのパーティショニング式で参照されるカラムは主キーの一部である必要があります。 ただし、ユーザーパーティション化された NDB
テーブルを作成または変更するために使用される CREATE TABLE
または ALTER TABLE
ステートメントの PARTITION BY KEY
句または PARTITION BY LINEAR KEY
句にカラムが 1 つもリストされていない場合は、テーブルに明示的な主キーは必要ありません。 詳細は、セクション23.1.7.1「NDB Cluster の SQL 構文に準拠していません」を参照してください。
パーティション化されたテーブルを作成する場合、デフォルトのストレージエンジンはほかのテーブルを作成する場合と同様に使用されます。この動作をオーバーライドするには、パーティション化されていないテーブルの場合と同様に[STORAGE] ENGINE
オプションを使用するだけで済みます。 ターゲットストレージエンジンは、ネイティブパーティショニングサポートを提供する必要があります。そうしないと、ステートメントは失敗します。 CREATE TABLE
ステートメントでパーティション化オプションを使用する前に、[STORAGE] ENGINE
(およびその他のテーブルオプション) をリストする必要があることに注意してください。 次の例では、ハッシュによって 6 つのパーティションにパーティション化され、(default_storage_engine
の値に関係なく) InnoDB
ストレージエンジンを使用するテーブルを作成する方法を示します:
CREATE TABLE ti (id INT, amount DECIMAL(7,2), tr_date DATE)
ENGINE=INNODB
PARTITION BY HASH( MONTH(tr_date) )
PARTITIONS 6;
各 PARTITION
句に [STORAGE] ENGINE
オプションを含めることはできますが、MySQL 8.0 ではこれは効果がありません。
特に指定がないかぎり、この説明の残りの例では、default_storage_engine
が InnoDB
であると想定しています。
パーティショニングはテーブルのすべてのデータおよびインデックスに適用されます。データだけにパーティション化しインデックスは行わないことはできず (その逆も不可)、テーブルの一部のみをパーティション化することもできません。
各パーティションのデータおよびインデックスを特定のディレクトリに割り当てるには、パーティション化されたテーブルを作成するために使用する CREATE TABLE
ステートメントの PARTITION
句に DATA DIRECTORY
および INDEX DIRECTORY
オプションを使用します。
InnoDB
テーブルの個々のパーティションおよびサブパーティションでは、DATA DIRECTORY
オプションのみがサポートされます。 MySQL 8.0.21 では、DATA DIRECTORY
句で指定されたディレクトリは InnoDB
で認識されている必要があります。 詳細は、DATA DIRECTORY 句の使用を参照してください。
テーブルのパーティション化式で使用されるすべてのカラムは、主キーを含め、テーブルに含まれる可能性のあるすべての一意キーの一部である必要があります。 つまり、次の SQL ステートメントで作成されたこのようなテーブルはパーティション化できません:
CREATE TABLE tnp (
id INT NOT NULL AUTO_INCREMENT,
ref BIGINT NOT NULL,
name VARCHAR(255),
PRIMARY KEY pk (id),
UNIQUE KEY uk (name)
);
キー pk
と uk
には共通のカラムがないため、パーティション化式で使用できるカラムはありません。 この状況で考えられる回避策には、name
カラムのテーブル主キーへの追加、id
カラムの uk
への追加、または一意キーの完全な削除が含まれます。 詳しくはセクション24.6.1「パーティショニングキー、主キー、および一意キー」,をご覧ください。
また、MAX_ROWS
および MIN_ROWS
は、各パーティションに格納できる行のそれぞれ最大数および最小数を決定するために使用できます。 これらのオプションの詳細は、セクション24.3「パーティション管理」 を参照してください。
MAX_ROWS
オプションは、余分なパーティションを含む「NDB Cluster」テーブルを作成する場合にも役立つため、ハッシュインデックスの記憶域を増やすことができます。 詳細は、DataMemory
データノード構成パラメータのドキュメント、および セクション23.1.2「NDB Cluster ノード、ノードグループ、フラグメントレプリカ、およびパーティション」を参照してください。
パーティショニングのいくつかの利点を次に示します。
パーティショニングを使用すると、単一ディスクまたはファイルシステムパーティションに保持できるデータより多くのデータを 1 つのテーブルに格納できます。
有効性を失っているデータは、多くの場合、そのデータのみが含まれているパーティションを削除することによって、パーティション化されたテーブルから簡単に削除できます。 反対に、新しいデータを追加する処理は、そのデータだけを格納するための 1 つ以上の新しいパーティションを追加することによって、非常に便利になることがあります。
-
指定された
WHERE
句を満たすデータを 1 つ以上のパーティションのみに格納できることによって、検索からほかのパーティションが自動的に除外され、一部のクエリーが大幅に最適化されることがあります。 パーティションはパーティション化されたテーブルが作成されたあとに変更できるため、使用頻度の高いクエリー (パーティショニングスキームが最初に設定されたときはあまり使用されていなかった) を改善するためにデータを再編成できます。 一致しないパーティション (およびそれらに含まれている行) を除外するこの機能は、よくパーティションプルーニングと呼ばれます。 詳細は、セクション24.4「パーティションプルーニング」を参照してください。また、MySQL では、クエリーの明示的なパーティション選択もサポートされています。 たとえば、
SELECT * FROM t PARTITION (p0,p1) WHERE c < 5
は、パーティションp0
およびp1
のWHERE
条件に一致する行のみを選択します。 この場合、MySQL はテーブルt
のほかのパーティションをチェックしません。これにより、検査するパーティションが事前にわかっているときにクエリー速度が大幅に向上することがあります。 パーティション選択は、データ変更ステートメント (DELETE
、INSERT
、REPLACE
、UPDATE
、LOAD DATA
、およびLOAD XML
) でもサポートされます。 詳細および例については、これらのステートメントの説明を参照してください。