MySQL 8.0 リファレンスマニュアル


MySQL 8.0 リファレンスマニュアル  /  パーティション化  /  パーティショニングの制約と制限

24.6 パーティショニングの制約と制限

このセクションでは、MySQL パーティショニングサポートでの現在の制約と制限について説明します。

禁止されている構造体.  次の構造体はパーティショニング式で許可されません。

  • ストアドプロシージャー、ストアドファンクション、UDF、またはプラグイン。

  • 宣言された変数またはユーザー変数。

パーティショニング式で許可される SQL 関数のリストについては、セクション24.6.3「関数に関連するパーティショニング制限」を参照してください。

算術および論理演算子.  算術演算子 +-、および * の使用は、パーティショニング式で許可されます。 ただし、結果は整数値または NULL である必要があります (この章のほかの場所で説明しているように、[LINEAR] KEY パーティショニングの場合を除きます。詳細は、セクション24.2「パーティショニングタイプ」を参照してください)。

DIV 演算子もサポートされています。/演算子は使用できません。

ビット演算子 |&^<<>>、および ~ はパーティショニング式では許可されません。

サーバー SQL モード.  ユーザー定義パーティショニングを使用するテーブルは、それらが作成された時点で有効だった SQL モードを保持しません。 このマニュアルの他の場所で説明されているように (セクション5.1.11「サーバー SQL モード」 を参照)、多くの MySQL 関数および演算子の結果は、サーバーの SQL モードに応じて変わる可能性があります。 このため、パーティション化されたテーブルの作成後の任意の時点に SQL モードを変更すると、そのようなテーブルの動作が大きく変わることがあり、データの破損または損失が発生しやすくなることがあります。 これらの理由により、パーティション化されたテーブルを作成したあとにサーバー SQL モードを決して変更しないことが強く推奨されています

パーティション化されたテーブルを使用不可にするサーバー SQL モードでこのような変更を行う場合は、NO_UNSIGNED_SUBTRACTION モードが有効な場合にのみ正常に実行できる次の CREATE TABLE ステートメントを検討してください:

mysql> SELECT @@sql_mode;
+------------+
| @@sql_mode |
+------------+
|            |
+------------+
1 row in set (0.00 sec)

mysql> CREATE TABLE tu (c1 BIGINT UNSIGNED)
    ->   PARTITION BY RANGE(c1 - 10) (
    ->     PARTITION p0 VALUES LESS THAN (-5),
    ->     PARTITION p1 VALUES LESS THAN (0),
    ->     PARTITION p2 VALUES LESS THAN (5),
    ->     PARTITION p3 VALUES LESS THAN (10),
    ->     PARTITION p4 VALUES LESS THAN (MAXVALUE)
    -> );
ERROR 1563 (HY000): Partition constant is out of partition function domain

mysql> SET sql_mode='NO_UNSIGNED_SUBTRACTION';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @@sql_mode;
+-------------------------+
| @@sql_mode              |
+-------------------------+
| NO_UNSIGNED_SUBTRACTION |
+-------------------------+
1 row in set (0.00 sec)

mysql> CREATE TABLE tu (c1 BIGINT UNSIGNED)
    ->   PARTITION BY RANGE(c1 - 10) (
    ->     PARTITION p0 VALUES LESS THAN (-5),
    ->     PARTITION p1 VALUES LESS THAN (0),
    ->     PARTITION p2 VALUES LESS THAN (5),
    ->     PARTITION p3 VALUES LESS THAN (10),
    ->     PARTITION p4 VALUES LESS THAN (MAXVALUE)
    -> );
Query OK, 0 rows affected (0.05 sec)

tu を作成したあとに NO_UNSIGNED_SUBTRACTION サーバー SQL モードを削除すると、このテーブルにアクセスできなくなる可能性があります。

mysql> SET sql_mode='';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM tu;
ERROR 1563 (HY000): Partition constant is out of partition function domain
mysql> INSERT INTO tu VALUES (20);
ERROR 1563 (HY000): Partition constant is out of partition function domain

セクション5.1.11「サーバー SQL モード」も参照してください。

サーバー SQL モードは、パーティション化されたテーブルのレプリケーションにも影響します。 ソースとレプリカで SQL モードを変えると、パーティション化式が異なる方法で評価される可能性があります。これにより、パーティション間でのデータの分散が特定のテーブルのソースとレプリカコピーで異なる可能性があり、ソースで成功したパーティションテーブルへの挿入がレプリカで失敗する可能性もあります。 最良の結果を得るには、ソースとレプリカで常に同じサーバー SQL モードを使用する必要があります。

パフォーマンス考慮事項.  パーティション化操作がパフォーマンスに与える影響の一部を次に示します:

  • ファイルシステム操作.  パーティション化および再パーティション化操作 (PARTITION BY ...REORGANIZE PARTITIONREMOVE PARTITIONING を使用した ALTER TABLE など) は、実装のためのファイルシステム操作に依存します。 これは、これらの操作の速度が、ファイルシステムのタイプと特性、ディスク速度、スワップ領域、オペレーティングシステムによるファイル処理効率、ファイル処理に関連する MySQL サーバーのオプションと変数などの要因に影響されることを意味します。 特に、large_files_support が有効になっていて、open_files_limit が適切に設定されていることを確認してください。 innodb_file_per_table を有効にすると、InnoDB テーブルを含むパーティション化および再パーティション化操作がより効率的になります。

    パーティションの最大数も参照してください。

  • テーブルロック.  通常、テーブルに対してパーティション化操作を実行するプロセスは、テーブルに対する書込みロックを取得します。 そのようなテーブルからの読み取りは比較的影響を受けません。保留中の INSERT および UPDATE 操作は、パーティショニング操作が完了するとすぐに実行されます。 この制限に対する InnoDB 固有の例外については、パーティション化操作 を参照してください。

  • インデックス、パーティションプルーニング.  パーティション化されていないテーブルと同様に、インデックスを適切に使用することで、パーティション化されたテーブルに対する照会速度が大幅に向上することがあります。 また、パーティション化されたテーブルおよびこれらのテーブルに対するクエリーをパーティションプルーニングの利点を活用するように設計することで、パフォーマンスが劇的に向上することがあります。 詳細は、セクション24.4「パーティションプルーニング」を参照してください。

    インデックス条件プッシュダウンは、パーティションテーブルでサポートされています。 セクション8.2.1.6「インデックスコンディションプッシュダウンの最適化」を参照してください。

  • LOAD DATA のパフォーマンス.  MySQL 8.0 では、LOAD DATA はパフォーマンスを向上させるためにバッファリングを使用します。 これを実現するために、バッファーがパーティションごとに 130K バイトメモリーを使用することを認識してください。

パーティションの最大数.  NDB ストレージエンジンを使用しない特定のテーブルで可能なパーティションの最大数は 8192 です。 この数にはサブパーティションが含まれます。

NDB ストレージエンジンを使用するテーブルのユーザー定義パーティションの最大数は、使用されている NDB Cluster ソフトウェアのバージョン、データノードの数、およびその他の要因に応じて決定されます。 詳細は、NDB とユーザー定義のパーティション化を参照してください。

多数のパーティション (ただし、最大数より少ない) を持つテーブルを作成するときに、Got error ... from storage engine: Out of resources when opening fileなどのエラーメッセージが表示される場合は、open_files_limit システム変数の値を増やすことによってこの問題に対処できることがあります。 ただし、これはオペレーティングシステムによって異なるため、すべてのプラットフォームで可能または推奨されるとはかぎりません。詳細は、セクションB.3.2.16「ファイルが見つからず同様のエラーが発生しました」を参照してください。 場合によっては、多数の (数百の) パーティションを使用することがほかの問題のために推奨されないこともあり、より多くのパーティションを使用することが自動的に良い結果となるとはかぎりません。

ファイルシステム操作も参照してください。

パーティション化された InnoDB テーブルで外部キーがサポートされない.  InnoDB ストレージエンジンを使用するパーティション化されたテーブルでは、外部キーはサポートされません。 これは具体的には、次の 2 つの記述が true であることを意味します。

  1. ユーザー定義パーティショニングを使用する InnoDB テーブルの定義には、外部キー参照を含めることはできません。定義に外部キー参照が含まれる InnoDB テーブルはパーティション化できません。

  2. InnoDB テーブル定義に、ユーザーパーティション化されたテーブルへの外部キー参照を含めることはできません。ユーザー定義パーティショニングを持つ InnoDB テーブルに、外部キーによって参照されるカラムを含めることはできません。

上記の制約のスコープには、InnoDB ストレージエンジンを使用するすべてのテーブルが含まれます。 結果のテーブルがこれらの制約に違反する CREATE TABLE および ALTER TABLE ステートメントは許可されません。

ALTER TABLE ... ORDER BY.  パーティション化されたテーブルに ALTER TABLE ... ORDER BY column ステートメントを実行すると、各パーティション内でのみ行が並べ替えられます。

主キーを変更することによる REPLACE ステートメントへの影響.  テーブルの主キーを変更することが望ましい場合があります (セクション24.6.1「パーティショニングキー、主キー、および一意キー」を参照してください)。 REPLACE ステートメントを使用するアプリケーションでこれを行うと、これらのステートメントの結果が大きく変わることがあることを認識してください。 詳細および例については、セクション13.2.9「REPLACE ステートメント」を参照してください。

FULLTEXT インデックス.  パーティションテーブルでは、FULLTEXT インデックスまたは検索はサポートされていません。

空間カラム.  POINTGEOMETRY などの空間データ型を持つカラムは、パーティション化されたテーブルで使用できません。

一時テーブル.  一時テーブルはパーティション化できません

ログテーブル.  ログテーブルをパーティション化することはできません。そのようなテーブルに ALTER TABLE ... PARTITION BY ... ステートメントを実行すると、エラーで失敗します。

パーティショニングキーのデータ型.  パーティショニングキーは、整数カラム、または整数に解決される式である必要があります。 ENUM カラムを使用する式は使用できません。 カラムまたは式の値は NULL でもかまいません。セクション24.2.7「MySQL パーティショニングによる NULL の扱い」 を参照してください。

この制約には 2 つの例外があります。

  1. [LINEAR] KEY でパーティション化する場合、TEXT または BLOB 以外の有効な MySQL データ型のカラムをパーティション化キーとして使用できます。これは、内部キーハッシュ関数がこれらの型から正しいデータ型を生成するためです。 たとえば、次の 2 つの CREATE TABLE ステートメントは有効です。

    CREATE TABLE tkc (c1 CHAR)
    PARTITION BY KEY(c1)
    PARTITIONS 4;
    
    CREATE TABLE tke
        ( c1 ENUM('red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet') )
    PARTITION BY LINEAR KEY(c1)
    PARTITIONS 6;
  2. RANGE COLUMNS または LIST COLUMNS によってパーティショニングするときは、文字列、DATE、および DATETIME カラムを使用できます。 たとえば、次の各 CREATE TABLE ステートメントは有効です。

    CREATE TABLE rc (c1 INT, c2 DATE)
    PARTITION BY RANGE COLUMNS(c2) (
        PARTITION p0 VALUES LESS THAN('1990-01-01'),
        PARTITION p1 VALUES LESS THAN('1995-01-01'),
        PARTITION p2 VALUES LESS THAN('2000-01-01'),
        PARTITION p3 VALUES LESS THAN('2005-01-01'),
        PARTITION p4 VALUES LESS THAN(MAXVALUE)
    );
    
    CREATE TABLE lc (c1 INT, c2 CHAR(1))
    PARTITION BY LIST COLUMNS(c2) (
        PARTITION p0 VALUES IN('a', 'd', 'g', 'j', 'm', 'p', 's', 'v', 'y'),
        PARTITION p1 VALUES IN('b', 'e', 'h', 'k', 'n', 'q', 't', 'w', 'z'),
        PARTITION p2 VALUES IN('c', 'f', 'i', 'l', 'o', 'r', 'u', 'x', NULL)
    );

上記の例外は、BLOB または TEXT カラム型には該当しません。

サブクエリー.  パーティショニングキーはサブクエリーにできません (そのサブクエリーが整数値または NULL に解決される場合でも)。

カラムインデックス接頭辞はキーパーティション化ではサポートされていません.  キーでパーティション化されたテーブルを作成する場合、カラム接頭辞を使用するパーティション化キー内のカラムは、テーブルパーティション化関数では使用されません。 3 つの VARCHAR カラムがあり、主キーが 3 つのカラムすべてを使用し、それらのうちの 2 つに接頭辞を指定する次の CREATE TABLE ステートメントについて考えてみます:

CREATE TABLE t1 (
    a VARCHAR(10000),
    b VARCHAR(25),
    c VARCHAR(10),
    PRIMARY KEY (a(10), b, c(2))
) PARTITION BY KEY() PARTITIONS 2;

このステートメントは受け入れられますが、結果のテーブルは、パーティション化キーの接頭辞 (カラム b) を含まない主キーカラムのみを使用して、次のステートメントを発行したかのように実際に作成されます:

CREATE TABLE t1 (
    a VARCHAR(10000),
    b VARCHAR(25),
    c VARCHAR(10),
    PRIMARY KEY (a(10), b, c(2))
) PARTITION BY KEY(b) PARTITIONS 2;

MySQL 8.0.21 より前は、次に示すように、パーティション化キーに指定されたすべてのカラムで接頭辞が使用された場合を除き、警告は発行されず、それ以外の場合は、ステートメントは失敗しましたが、誤解を招くエラーメッセージが表示されます:

mysql> CREATE TABLE t2 (
    ->     a VARCHAR(10000),
    ->     b VARCHAR(25),
    ->     c VARCHAR(10),
    ->     PRIMARY KEY (a(10), b(5), c(2))
    -> ) PARTITION BY KEY() PARTITIONS 2;
ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the
table's partitioning function

これは、ALTER TABLE の実行時またはこのようなテーブルのアップグレード時にも発生します。

この許容動作は、MySQL 8.0.21 では非推奨です (将来のバージョンの MySQL では削除される可能性があります)。 MySQL 8.0.21 以降では、パーティション化キーに接頭辞を持つカラムを使用すると、次に示すように、そのようなカラムごとに警告が表示されます:

mysql> CREATE TABLE t1 (
    ->     a VARCHAR(10000),
    ->     b VARCHAR(25),
    ->     c VARCHAR(10),
    ->     PRIMARY KEY (a(10), b, c(2))
    -> ) PARTITION BY KEY() PARTITIONS 2;
Query OK, 0 rows affected, 2 warnings (1.25 sec)

mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
  Level: Warning
   Code: 1681
Message: Column 'test.t1.a' having prefix key part 'a(10)' is ignored by the
partitioning function. Use of prefixed columns in the PARTITION BY KEY() clause
is deprecated and will be removed in a future release.
*************************** 2. row ***************************
  Level: Warning
   Code: 1681
Message: Column 'test.t1.c' having prefix key part 'c(2)' is ignored by the
partitioning function. Use of prefixed columns in the PARTITION BY KEY() clause
is deprecated and will be removed in a future release.
2 rows in set (0.00 sec)

これには、空の PARTITION BY KEY() 句を使用して、パーティション化関数で使用されるカラムがテーブルの主キーのカラムとして暗黙的に定義される場合が含まれます。

MySQL 8.0.21 以降では、パーティション化キーに指定されたすべてのカラムに接頭辞が使用されている場合、使用される CREATE TABLE ステートメントは失敗し、問題を正しく識別するエラーメッセージが表示されます:

mysql> CREATE TABLE t1 (
    ->     a VARCHAR(10000),
    ->     b VARCHAR(25),
    ->     c VARCHAR(10),
    ->     PRIMARY KEY (a(10), b(5), c(2))
    -> ) PARTITION BY KEY() PARTITIONS 2;
ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the table's
partitioning function (prefixed columns are not considered).

キーによるテーブルのパーティション化の一般情報は、セクション24.2.5「KEY パーティショニング」 を参照してください。

サブパーティションに関する問題.  サブパーティションは HASH または KEY パーティショニングを使用する必要があります。 サブパーティション化できるのは RANGE および LIST パーティションのみです。HASH および KEY パーティションはサブパーティション化できません。

SUBPARTITION BY KEY では、PARTITION BY KEY の場合とは異なり、サブパーティション化カラムを明示的に指定する必要があります。ここでは省略できます (この場合、テーブルの主キーカラムがデフォルトで使用されます)。 次のステートメントによって作成されたテーブルがあるとします。

CREATE TABLE ts (
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(30)
);

次のようなステートメントを使用することで、KEY によってパーティション化された、同じカラムを持つテーブルを作成できます。

CREATE TABLE ts (
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(30)
)
PARTITION BY KEY()
PARTITIONS 4;

前のステートメントは、次のように記述されているかのように扱われます (テーブルの主キーカラムがパーティショニングカラムとして使用されます)。

CREATE TABLE ts (
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(30)
)
PARTITION BY KEY(id)
PARTITIONS 4;

ただし、次のステートメントは、デフォルトカラムをサブパーティショニングカラムとして使用するサブパーティション化されたテーブルを作成しようとするため失敗します。このステートメントが成功するには次のようにカラムを指定する必要があります。

mysql> CREATE TABLE ts (
    ->     id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    ->     name VARCHAR(30)
    -> )
    -> PARTITION BY RANGE(id)
    -> SUBPARTITION BY KEY()
    -> SUBPARTITIONS 4
    -> (
    ->     PARTITION p0 VALUES LESS THAN (100),
    ->     PARTITION p1 VALUES LESS THAN (MAXVALUE)
    -> );
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near ')

mysql> CREATE TABLE ts (
    ->     id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    ->     name VARCHAR(30)
    -> )
    -> PARTITION BY RANGE(id)
    -> SUBPARTITION BY KEY(id)
    -> SUBPARTITIONS 4
    -> (
    ->     PARTITION p0 VALUES LESS THAN (100),
    ->     PARTITION p1 VALUES LESS THAN (MAXVALUE)
    -> );
Query OK, 0 rows affected (0.07 sec)

これは既知の問題です (Bug #51470 を参照してください)。

DATA DIRECTORY および INDEX DIRECTORY オプション.  テーブルレベル DATA DIRECTORY および INDEX DIRECTORY オプションは無視されます (Bug #32091 を参照してください)。 これらのオプションは、InnoDB テーブルの個々のパーティションまたはサブパーティションに使用できます。 MySQL 8.0.21 では、DATA DIRECTORY 句で指定されたディレクトリは InnoDB で認識されている必要があります。 詳細は、DATA DIRECTORY 句の使用を参照してください。

パーティション化されたテーブルを修復および再構築する.  ステートメント CHECK TABLEOPTIMIZE TABLEANALYZE TABLE、および REPAIR TABLE がパーティション化されたテーブルでサポートされます。

また、ALTER TABLE ... REBUILD PARTITION を使用することで、パーティション化されたテーブルの 1 つ以上のパーティションを再構築できます。ALTER TABLE ... REORGANIZE PARTITION でもパーティションが再構築されます。 これら 2 つのステートメントの詳細については、セクション13.1.9「ALTER TABLE ステートメント」を参照してください。

サブパーティションでは、ANALYZE, CHECK, OPTIMIZE, REPAIR および TRUNCATE 操作がサポートされています。 セクション13.1.9.1「ALTER TABLE パーティション操作」を参照してください。

パーティションおよびサブパーティションのファイル名デリミタ.  テーブルパーティションおよびサブパーティションファイルの名前には、#P##SP#などの生成されたデリミタが含まれます。 このようなデリミタの大文字と小文字は異なる場合があるため、依存しないでください。


関連キーワード:  テーブル, PARTITION, KEY, TABLE, パーティショニング, カラム, ステートメント, 参照, VALUES, CREATE