2026年8月7日
2026年8月7日
WordPressのDBテーブルをOPTIMIZE TABLEで最適化し、断片化を解消する方法
WordPressのデータベースで「断片化」を解消したいときは、まず不要データを削除し、次に空き領域の大きいテーブルだけを OPTIMIZE TABLE で再構築する、という順番で進めます。この記事では、断片化の量を数値で確かめる方法、phpMyAdmin・WP-CLI・プラグインそれぞれでの実行手順、InnoDB特有の注意点、効果の確認方法までを説明します。
断片化とは何か、OPTIMIZE TABLEで何が起きるのか
WordPressのテーブルでは、記事の更新や削除、リビジョンやトランジェントの追加と削除が日常的に起きています。行を削除しても、その分のディスク領域はすぐにはOSへ返されず、テーブルの中に「使われていない隙間」として残ります。これが断片化です。大量のリビジョンを一括削除した直後などは、データ量は減ったのにファイルサイズは変わらない、という状態になります。
OPTIMIZE TABLE は、テーブルを作り直してこの隙間を詰める命令です。現在のWordPressで標準的なストレージエンジンであるInnoDBの場合、MySQLは内部的にテーブルの再作成と統計情報の更新(ALTER TABLE ... FORCE と ANALYZE TABLE に相当する処理)を行います。そのため実行結果に「Table does not support optimize, doing recreate + analyze instead」というメッセージが出ますが、これはエラーではなく、InnoDBでは通常の表示です。最後の行が OK になっていれば成功しています。
あらかじめ知っておきたいのは、OPTIMIZEで大きく速くなるケースは多くない、という点です。InnoDBはインデックスを使って必要な行を探すため、隙間があるだけで検索が極端に遅くなることは通常ありません。主な効果はディスク使用量の削減と、統計情報が新しくなることによる実行計画の改善です。サイトの表示が遅い原因を探している場合は、autoloadされるオプションの肥大化や、遅いクエリの有無も合わせて確認してください。
実行前に確認すること
バックアップを取る
OPTIMIZEはテーブルを作り直す操作です。途中でディスクがいっぱいになったり、接続が切れたりする可能性はゼロではありません。実行前にデータベース全体をエクスポートしておきます。WP-CLIが使える環境なら次の1行で取れます。
wp db export backup-before-optimize.sql
大規模なサイトや、初めて作業する本番環境では、ステージング環境に複製して一度試してから本番に適用すると安心です。
ディスクの空き容量
InnoDBのテーブルを再構築するときは、元のテーブルとほぼ同じ大きさの一時領域が必要になります。wp_postmeta が2GBあるなら、少なくとも同程度の空きがないと途中で失敗します。共有レンタルサーバーではディスク容量の上限に当たりやすいので、管理画面などで残り容量を確認してから進めてください。
innodb_file_per_table が有効か
再構築で空いた領域がOSに返されるのは、テーブルごとに個別のファイル(.ibd)を持つ設定 innodb_file_per_table が有効な場合です。MySQL 5.6.6以降では既定で有効ですが、古い環境から移行してきたサーバーでは無効のままのこともあります。
SHOW VARIABLES LIKE 'innodb_file_per_table';
OFF の場合、テーブルは共有領域(ibdata1)に入っており、OPTIMIZEしてもibdata1ファイル自体は小さくなりません。この場合は効果が限られることを理解したうえで実行するか、サーバー管理者に相談してください。
断片化の量を数値で確認する
やみくもに全テーブルを最適化するのではなく、空き領域が大きいテーブルを特定します。phpMyAdminの「SQL」タブ、またはWP-CLIの wp db query で次のクエリを実行します。
SELECT table_name,
engine,
ROUND(data_length / 1024 / 1024, 1) AS data_mb,
ROUND(index_length / 1024 / 1024, 1) AS index_mb,
ROUND(data_free / 1024 / 1024, 1) AS free_mb
FROM information_schema.tables
WHERE table_schema = DATABASE()
ORDER BY data_free DESC;
free_mb(DATA_FREE)が、テーブル内に残っている未使用領域の目安です。データ量に対して空き領域の割合が大きいテーブルが、最適化する価値のある候補になります。WordPressでは wp_posts、wp_postmeta、wp_options、wp_comments、wp_commentmeta などが上位に来ることが多いでしょう。
この数値は正確な値ではなく概算です。InnoDBではページ単位で管理されているため、小さなテーブルでは0と表示されたり、数MB単位で丸められたりします。また、MySQL 8.0では information_schema の統計値がキャッシュされるため、直前の削除が反映されていないことがあります。最新の値を見たいときは、対象テーブルに ANALYZE TABLE wp_postmeta; を実行してから再度確認します。
テーブル名の接頭辞が wp_ ではないサイトも多いので、wp db prefix で実際の接頭辞を確かめてから作業してください。
先に不要データを削除する
OPTIMIZEは隙間を詰めるだけで、データそのものは減らしません。リビジョンや期限切れトランジェントが大量に残っているなら、それを先に削除し、その後でOPTIMIZEすると効果が出やすくなります。
期限切れのトランジェントはWP-CLIで削除できます。
wp transient delete --expired
リビジョンは、WP-Optimize や Advanced Database Cleaner といったプラグインの掃除機能で削除する方法が手軽です。今後のリビジョン数を抑えたい場合は、wp-config.php に define( 'WP_POST_REVISIONS', 5 ); のように上限を設定しておきます。削除系の操作は元に戻せないため、ここでも先ほどのバックアップがあることを確認してください。
OPTIMIZE TABLEを実行する
WP-CLIで実行する
WP-CLIの wp db optimize は、データベース内のテーブルをまとめて最適化します(内部では mysqlcheck を使います)。
wp db optimize
特定のテーブルだけを対象にしたい場合は、SQLを直接実行します。
wp db query "OPTIMIZE TABLE wp_postmeta, wp_options;"
phpMyAdminで実行する
phpMyAdminでは、対象データベースのテーブル一覧で最適化したいテーブルにチェックを入れ、一覧下部の一括操作メニューから「テーブルを最適化する」(英語表示では Optimize table)を選びます。表記はphpMyAdminのバージョンや言語設定によって異なることがあります。SQLタブで OPTIMIZE TABLE wp_postmeta; と入力しても同じです。
WordPressの修復画面を使う
WP-CLIもphpMyAdminも使えない環境では、wp-config.php に次の1行を一時的に追加すると、/wp-admin/maint/repair.php で「データベースを修復し最適化」を実行できます。
define( 'WP_ALLOW_REPAIR', true );
この画面はログインなしでアクセスできるため、作業が終わったらすぐに行を削除してください。
実行のタイミング
MySQL 5.6以降のInnoDBでは、通常のテーブルのOPTIMIZEはオンラインDDLとして処理され、再構築中も読み書きの多くが可能です。ただし処理の開始時と終了時には短時間のロックがかかり、全文検索インデックスを持つテーブルなど、条件によってはオンライン処理にならない場合もあります。MyISAMのテーブルでは処理中ずっとテーブルがロックされます。数百MBを超えるテーブルを扱うときは、アクセスの少ない時間帯を選んでください。
頻度は、日常的に実行する必要はありません。大量の削除をした後や、数か月に一度の定期メンテナンスとして行えば十分です。
効果を確認する
実行後、先ほどの information_schema のクエリをもう一度実行し、free_mb と data_mb が減っているかを比べます。wp db size --tables でもテーブルごとのサイズを確認できます。
数値が変わらない場合は、次の点を見直してください。
innodb_file_per_tableがOFFで、共有領域に入っている- 統計情報が古いまま表示されている(ANALYZE TABLEの後に再確認する)
- もともと隙間が小さく、再構築しても差がほとんどなかった
あわせて、サイトの表示や管理画面の操作に異常がないか、エラーログに新しいエラーが出ていないかも確認します。
まとめ
- 断片化は削除後に残る未使用領域で、
OPTIMIZE TABLEはテーブルを再構築してそれを詰める - InnoDBの「doing recreate + analyze instead」は正常なメッセージ
- 実行前にバックアップ、ディスクの空き容量、
innodb_file_per_tableを確認する - information_schema の DATA_FREE で空き領域の大きいテーブルを見つけ、そこだけを対象にする
- 不要データの削除を先に行い、その後でOPTIMIZEすると効果が出やすい
- 表示速度の改善は限定的なことが多いので、遅さの原因は別途調べる
- 本記事は、MySQL 8系とMariaDBの一般的な挙動を前提にしています(2026年10月現在)