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


13.7.3.4 OPTIMIZE TABLE ステートメント

OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL]
    TABLE tbl_name [, tbl_name] ...

OPTIMIZE TABLE では、テーブルデータおよび関連するインデックスデータの物理記憶域が再編成され、記憶領域が削減され、テーブルへのアクセス時の I/O の効率が向上します。 各テーブルに加えられる正確な変更は、そのテーブルによって使用されているストレージエンジンによって異なります。

OPTIMIZE TABLE は、テーブルのタイプに応じて次の場合に使用します。

  • innodb_file_per_table オプションが有効な状態で作成されたために独自の .ibd ファイル を含む InnoDB テーブルに対して大量の挿入、更新、または削除操作を行なったあと。 テーブルとインデックスが再編成されるため、ディスク領域をオペレーティングシステムによる使用のために再利用できます。

  • InnoDB テーブル内の FULLTEXT インデックスの一部であるカラムに対して大量の挿入、更新、または削除操作を行なったあと。 最初に、構成オプション innodb_optimize_fulltext_only=1 を設定します。 インデックスの保守期間を妥当な時間に維持するために、検索インデックスで更新するワード数を指定する innodb_ft_num_word_optimize オプションを設定し、検索インデックスが完全に更新されるまで OPTIMIZE TABLE ステートメントのシーケンスを実行します。

  • MyISAM または ARCHIVE テーブルの大きな部分を削除するか、あるいは可変長行を含む MyISAM または ARCHIVE テーブル (VARCHARVARBINARYBLOB、または TEXT カラムを含むテーブル) に多くの変更を行なったあと。 削除された行はリンクリスト内に保持され、以降の INSERT 操作は古い行の位置を再利用します。 OPTIMIZE TABLE を使用すると、未使用領域を再利用したり、データファイルをデフラグしたりできます。 テーブルを大幅に変更したあとは、このステートメントにより、そのテーブルを使用するステートメントのパフォーマンスを (場合によっては大幅に) 向上させることができます。

このステートメントには、このテーブルに対する SELECT および INSERT 権限が必要です。

OPTIMIZE TABLE は、InnoDBMyISAM、および ARCHIVE テーブルに対して機能します。 OPTIMIZE TABLE は、インメモリー NDB テーブルの動的なカラムに対してもサポートされます。 インメモリーテーブルの固定幅カラムに対しては機能せず、「ディスクデータ」テーブルに対しても機能しません。 「NDB Cluster」テーブルの OPTIMIZE のパフォーマンスは、OPTIMIZE TABLE による行のバッチ処理間の待機時間を制御する --ndb-optimization-delay を使用してチューニングできます。 詳細は、セクション23.1.7.11「前 NDB Cluster 8.0 で解決される NDB Cluster の問題」を参照してください。

「NDB Cluster の場合」テーブルの OPTIMIZE TABLE は、OPTIMIZE 操作を実行している SQL スレッドを強制終了することで中断できます。

デフォルトでは、OPTIMIZE TABLE はその他のストレージエンジンを使用して作成されたテーブルに対しては機能せず、このサポートがないことを示す結果を返します。 --skip-new オプションを使用して mysqld を起動することによって、その他のストレージエンジンに対して OPTIMIZE TABLE を機能させることができます。 この場合、OPTIMIZE TABLE は単に ALTER TABLE にマップされます。

このステートメントはビューでは機能しません。

OPTIMIZE TABLE は、パーティションテーブルでサポートされています。 このステートメントのパーティション化されたテーブルでの使用やテーブルパーティションについては、セクション24.3.4「パーティションの保守」を参照してください。

デフォルトでは、OPTIMIZE TABLE ステートメントはレプリカにレプリケートされるようにバイナリログに書き込まれます。 ロギングを抑制するには、オプションの NO_WRITE_TO_BINLOG キーワード、またはそのエイリアス LOCAL を指定します。

OPTIMIZE TABLE の出力

OPTIMIZE TABLE は、次のテーブルに示すカラムを含む結果セットを返します。

カラム
Table テーブル名
Op 常に optimize
Msg_type statuserrorinfonote、または warning
Msg_text 情報メッセージ

OPTIMIZE TABLE テーブルは、古いファイルから新しく作成されたファイルへのテーブル統計のコピー中に発生したすべてのエラーをキャッチしてスローします。 たとえば、.MYD または .MYI ファイルの所有者のユーザー ID が mysqld プロセスのユーザー ID と異なる場合、OPTIMIZE TABLE では、root ユーザーが mysqld を起動しないかぎり、「ファイルの所有権を変更できません」というエラーが生成されます。

InnoDB の詳細

InnoDB テーブルの場合、OPTIMIZE TABLEALTER TABLE ... FORCE にマップされます。これは、インデックス統計を更新し、クラスタ化されたインデックス内の未使用領域を解放するためにテーブルを再構築します。 これは、次に示すように、InnoDB テーブルに対して実行したときに OPTIMIZE TABLE の出力に表示されます。

mysql> OPTIMIZE TABLE foo;
+----------+----------+----------+-------------------------------------------------------------------+
| Table    | Op       | Msg_type | Msg_text                                                          |
+----------+----------+----------+-------------------------------------------------------------------+
| test.foo | optimize | note     | Table does not support optimize, doing recreate + analyze instead |
| test.foo | optimize | status   | OK                                                                |
+----------+----------+----------+-------------------------------------------------------------------+

OPTIMIZE TABLE では、通常のパーティション化された InnoDB テーブルに online DDL が使用されるため、同時 DML 操作の停止時間が短縮されます。 OPTIMIZE TABLE によってトリガーされたテーブルの再構築が適切に完了します。 排他テーブルロックは、操作の準備フェーズおよびコミットフェーズでのみ短時間実行されます。 準備フェーズでは、メタデータが更新され、中間テーブルが作成されます。 コミットフェーズでは、テーブルメタデータの変更がコミットされます。

OPTIMIZE TABLE では、次の条件下でテーブルのコピー方法を使用してテーブルを再構築します:

  • old_alter_table システム変数が有効な場合。

  • --skip-new オプションを使用してサーバーを起動したとき。

online DDL を使用する OPTIMIZE TABLE は、FULLTEXT インデックスを含む InnoDB テーブルではサポートされていません。 かわりにテーブルのコピー方法が使用されます。

InnoDB は、ページの割当て方法を使用してデータを格納し、レガシーストレージエンジン (MyISAM など) と同様に断片化の影響を受けません。 最適化を実行するかどうかを検討する場合は、サーバーが処理すると予想されるトランザクションのワークロードを考慮してください:

  • ある程度の断片化は予測されます。 InnoDB は、ページを分割しなくても更新できる余地を残すために、ページを 93% までしかいっぱいにしません。

  • 削除操作によってギャップが残され、ページの空きが目的より多くなることがあります。これにより、テーブルを最適化する価値が生まれる可能性があります。

  • 行を更新すると通常、十分な領域が使用可能であれば、データ型と行フォーマットに応じて同じページ内のデータが書き換えられます。 セクション15.9.1.5「InnoDB テーブルでの圧縮の動作」およびセクション15.10「InnoDB の行フォーマット」を参照してください。

  • InnoDB はその MVCC メカニズムのために同じデータの複数のバージョンを保持するため、並列性の高いワークロードでは、時間の経過とともにインデックス内にギャップが残される可能性があります。 セクション15.3「InnoDB マルチバージョン」を参照してください。

MyISAM の詳細

MyISAM テーブルの場合、OPTIMIZE TABLE は次のように機能します。

  1. テーブルが行を削除または分割した場合は、そのテーブルを修復します。

  2. インデックスページがソートされていない場合は、それをソートします。

  3. テーブルの統計が最新でない (そのため、インデックスのソートによって修復を実行できない) 場合は、それを更新します。

その他の考慮事項

OPTIMIZE TABLE は、通常のパーティション化された InnoDB テーブルに対してオンラインで実行されます。 それ以外の場合は、OPTIMIZE TABLE の実行中に MySQL locks the table が実行されます。

OPTIMIZE TABLE は、POINT カラム上の空間インデックスなどの R ツリーインデックスをソートしません。 (Bug #23578)


関連キーワード:  ステートメント, TABLE, テーブル, OPTIMIZE, CREATE, InnoDB, DROP, インデックス, カラム, サブクエリー