MERGE
テーブルの既知の問題点は次のとおりです。
-
5.1.23 バージョンより前の MySQL Server では、MyISAM の非一時的な子供のテーブルを持つ一時的なマージテーブルを作成できました。
バージョン 5.1.23 からは、MERGE の子供は親のテーブルを介してロックされました。 親が一時的であった場合、親がロックされなかったため、子供もロックされませんでした。 MyISAM テーブルを同時に使用すると、テーブルが破損しました。
ALTER TABLE
を使用してMERGE
テーブルを別のストレージエンジンに変えると、基礎テーブルへのマッピングが失われます。 その代わり、変更されたテーブルに基礎MyISAM
テーブルの行がコピーされ、そのときに、指定されたストレージエンジンを使用します。MERGE
テーブルのINSERT_METHOD
テーブルオプションは、MERGE
テーブルへの挿入にどの基礎MyISAM
テーブルを使用するかを示します。 ただし、そのMyISAM
テーブルにAUTO_INCREMENT
テーブルオプションを使用しても、1 つ以上の行がMyISAM
テーブルに直接挿入されるまで、MERGE
テーブルへの挿入は有効になりません。MERGE
テーブルは、テーブル全体に一意制約を保持できません。INSERT
を実行すると、データは最初または最後のMyISAM
テーブル (INSERT_METHOD
オプションで指定されます) に入ります。 MySQL は一意のキー値がMyISAM
テーブル内で一意のままであることを保証しますが、コレクション内のすべての基礎テーブルには保証しません。-
MERGE
エンジンは基本テーブルセットに一意性を適用できないため、REPLACE
は期待どおりに機能しません。 次の 2 つの重要な事実があります。REPLACE
は、書き込もうとする基礎テーブルでのみ一意キー違反を検出できます (INSERT_METHOD
オプションで指定されます)。 これはMERGE
テーブル自体の違反とは異なります。REPLACE
は、一意キー違反を検出すると、書込み先の基礎となるテーブル (つまり、INSERT_METHOD
オプションで決定された最初または最後のテーブル) の対応する行のみを変更します。
INSERT ... ON DUPLICATE KEY UPDATE
についても同様な考慮が適用されます。 MERGE
テーブルはパーティション化をサポートしていません。 つまり、MERGE
テーブルも、MERGE
テーブルの基礎MyISAM
テーブルもパーティション化できません。-
開いた
MERGE
テーブルにマッピングされたどのテーブルにも、ANALYZE TABLE
、REPAIR TABLE
、OPTIMIZE TABLE
、ALTER TABLE
、DROP TABLE
、DELETE
(WHERE
句なし)、またはTRUNCATE TABLE
を使用すべきではありません。 そうする場合、MERGE
テーブルは引き続き元のテーブルを参照しているため、予期しない結果となる可能性があります。 この問題に対処するには、名前付きの操作を行う前にFLUSH TABLES
ステートメントを発行することで、確実にMERGE
テーブルが開いたままにならないようにします。予期しない結果には、
MERGE
テーブルに対する操作でテーブルの破損が報告される可能性があります。 基礎MyISAM
テーブルで名前付き操作のあとにこれが発生した場合、破損メッセージは偽りです。 これに対処するには、MyISAM
テーブルを変更したあとでFLUSH TABLES
ステートメントを発行します。 MERGE
ストレージエンジンのテーブルマッピングは MySQL の上位レイヤーから隠れているので、MERGE
テーブルによって使用されているテーブルでのDROP TABLE
は Windows では機能しません。 Windows では開いているファイルの削除を許可しないため、最初にすべてのMERGE
テーブルをフラッシュするか (FLUSH TABLES
を使用します)、テーブルを削除する前にMERGE
テーブルを削除する必要があります。MyISAM
テーブルとMERGE
テーブルの定義は、テーブルにアクセスするときにチェックされます (たとえば、SELECT
またはINSERT
ステートメントの一部として)。 このチェックは、テーブルの定義と親のMERGE
テーブルの定義が、カラムの順番、タイプ、サイズ、および関連するインデックスを比較することで一致することを保証します。 テーブル間で違いがある場合、エラーが戻され、ステートメントは失敗します。 これらのチェックはテーブルが開かれたときに行われるため、カラムの変更、カラムの順序付け、エンジンの変更など、単一のテーブルの定義を変更すると、ステートメントが失敗します。MERGE
テーブルと、その基礎テーブルのインデックスの順番は同一でなければいけません。ALTER TABLE
を使用して、MERGE
テーブル内で使用されるテーブルにUNIQUE
インデックスを追加し、次にALTER TABLE
を使用してMERGE
テーブル上に一意でないインデックスを追加した場合、基礎テーブル内に一意でないインデックスがすでに存在していると、それらのテーブルのインデックス順序は異なります。 (これが発生するのは、重複キーをすばやく検出できるようにALTER TABLE
が一意でないインデックスの前にUNIQUE
インデックスを配置するためです。) その結果、このようなインデックスを持つテーブルに対するクエリーは予想外の結果をもたらす可能性があります。ERROR 1017 (HY000): Can't find file: '
tbl_name
.MRG' (errno: 2)エラーメッセージが表示された場合、一般的に、いくつかの基礎テーブルがMyISAM
ストレージエンジンを使用していないことを表しています。 これらのテーブルがすべてMyISAM
であることを確認してください。MERGE
テーブルの行の最大値は 264 です (~1.844E+19 で、MyISAM
テーブルの場合と同じ)。 複数のMyISAM
テーブルを、この数よりも多くの行を含む単一のMERGE
テーブルにマージできません。親の
MERGE
テーブルを持つ、異なる行フォーマットの基礎MyISAM
テーブルを使用すると、現在失敗することが知られています。 バグ #32364 を参照してください。-
LOCK TABLES
が実施されているときは、非一時的なMERGE
テーブルの結合リストを変更できません。 次は動作しません。CREATE TABLE m1 ... ENGINE=MRG_MYISAM ...; LOCK TABLES t1 WRITE, t2 WRITE, m1 WRITE; ALTER TABLE m1 ... UNION=(t1,t2) ...;
ただし、一時的な
MERGE
テーブルではこれを行うことができます。 -
一時的な
MERGE
としても、非一時的なMERGE
テーブルとしても、CREATE ... SELECT
でMERGE
テーブルを作成できません。 例:CREATE TABLE m1 ... ENGINE=MRG_MYISAM ... SELECT ...;
これを試みると、
tbl_name
はBASE TABLE
ではないというエラーとなります。 あるケースでは、
MERGE
と基礎テーブル間でPACK_KEYS
テーブルオプション値が異なると、基礎テーブルにCHAR
またはBINARY
カラムが含まれている場合、予期しない結果になります。 回避策として、ALTER TABLE
を使用して、関係するすべてのテーブルのPACK_KEYS
値が同じであることを保証します。 (Bug #50646)