2026年9月12日
2026年9月12日
WordPressのデータベースを最適化する方法・テーブル最適化とクリーンアップ
はじめに
「管理画面の動作が重くなってきた」「データベースのサイズが大きくなりすぎている」——WordPressのデータベースは長期運用により断片化や不要データが蓄積します。定期的な最適化でサイトのパフォーマンスを維持できます。
症状・原因
WordPressのMySQLデータベースは投稿リビジョン・自動下書き・スパムコメント・削除済み投稿・期限切れTransientが蓄積して肥大化します。テーブルが断片化すると検索クエリが遅くなり、管理画面やフロントエンドの表示速度に影響します。
解決手順
ステップ1:データベースの現状を把握する
-- phpMyAdminのSQLタブで実行
-- テーブルごとのサイズを確認
SELECT
table_name AS 'テーブル名',
ROUND(data_length / 1024 / 1024, 2) AS 'データ(MB)',
ROUND(data_free / 1024 / 1024, 2) AS '未使用(MB)',
ROUND((data_length + index_length) / 1024 / 1024, 2) AS '合計(MB)'
FROM information_schema.tables
WHERE table_schema = 'wordpress_db' -- DB名を変更
ORDER BY (data_length + index_length) DESC;
-- Transientの数を確認
SELECT COUNT(*) FROM wp_options
WHERE option_name LIKE '_transient_%';
-- 投稿リビジョンの数を確認
SELECT COUNT(*) FROM wp_posts
WHERE post_type = 'revision';
# WP-CLIでデータベース情報を確認
wp db size
wp db size --tables
# データベースの状態を確認
wp db check
ステップ2:不要データを削除してDBを軽量化する
# WP-CLIで不要データを一括削除
# 投稿リビジョンを削除
wp post delete $(wp post list --post_type=revision --format=ids) --force
# 自動下書きを削除
wp post delete $(wp post list --post_status=auto-draft --format=ids) --force
# ゴミ箱内のデータを削除
wp post delete $(wp post list --post_status=trash --format=ids) --force
# スパムコメントを削除
wp comment delete $(wp comment list --status=spam --format=ids)
# 期限切れTransientを削除
wp transient delete --expired
-- SQLで一括削除(phpMyAdminで実行)
-- バックアップ後に実行すること!
-- 投稿リビジョンを削除
DELETE FROM wp_posts WHERE post_type = 'revision';
-- 自動下書きを削除
DELETE FROM wp_posts WHERE post_status = 'auto-draft';
-- ゴミ箱の投稿を削除
DELETE p, pm FROM wp_posts p
LEFT JOIN wp_postmeta pm ON pm.post_id = p.ID
WHERE p.post_status = 'trash';
-- 期限切れTransientを削除
DELETE FROM wp_options
WHERE option_name LIKE '_transient_%'
AND option_name LIKE '_transient_timeout_%';
-- 孤立したpostmetaを削除(投稿のないメタデータ)
DELETE pm FROM wp_postmeta pm
LEFT JOIN wp_posts p ON p.ID = pm.post_id
WHERE p.ID IS NULL;
ステップ3:テーブルを最適化する
-- OPTIMIZE TABLE でテーブルの断片化を解消
OPTIMIZE TABLE wp_posts;
OPTIMIZE TABLE wp_postmeta;
OPTIMIZE TABLE wp_options;
OPTIMIZE TABLE wp_comments;
OPTIMIZE TABLE wp_commentmeta;
OPTIMIZE TABLE wp_usermeta;
-- 全テーブルを一括最適化(phpMyAdmin → データベース選択 → 全選択 → 最適化)
# WP-CLIでテーブルを最適化
wp db optimize
# 特定テーブルを指定して最適化
wp db query "OPTIMIZE TABLE wp_posts, wp_postmeta, wp_options;"
# データベースを修復(テーブルが壊れた場合)
wp db repair
ステップ4:インデックスを追加してクエリを高速化する
-- wp_optionsテーブルのautoloadインデックス(よく使われる最適化)
-- autoload='yes'の項目が多い場合に効果的
SELECT COUNT(*), LENGTH(option_value)
FROM wp_options
WHERE autoload = 'yes'
GROUP BY autoload;
-- autoloadオプションのサイズが大きい場合のインデックス追加
-- (通常は既に存在するが念のため確認)
SHOW INDEX FROM wp_options WHERE Key_name = 'autoload';
-- wp_postmetaのmeta_keyにインデックスを追加(カスタムクエリ高速化)
-- 既存インデックスを確認
SHOW INDEX FROM wp_postmeta;
-- meta_key + meta_value の複合インデックス
ALTER TABLE wp_postmeta
ADD INDEX meta_key_value (meta_key(191), meta_value(100));
ステップ5:定期最適化を自動化する
// functions.php: WordPressのCronで定期最適化
add_action( 'wp', function() {
if ( ! wp_next_scheduled( 'my_db_optimize_event' ) ) {
wp_schedule_event( time(), 'weekly', 'my_db_optimize_event' );
}
} );
add_action( 'my_db_optimize_event', function() {
global $wpdb;
// 期限切れTransientを削除
$wpdb->query(
"DELETE FROM $wpdb->options
WHERE option_name LIKE '_transient_timeout_%'
AND option_value < " . time()
);
$wpdb->query(
"DELETE FROM $wpdb->options
WHERE option_name LIKE '_transient_%'
AND option_name NOT LIKE '_transient_timeout_%'
AND option_name NOT IN (
SELECT CONCAT('_transient_', SUBSTRING(option_name, 20))
FROM (SELECT option_name FROM $wpdb->options WHERE option_name LIKE '_transient_timeout_%') tmp
)"
);
// テーブルを最適化
$tables = $wpdb->get_results( "SHOW TABLES", ARRAY_N );
foreach ( $tables as $table ) {
$wpdb->query( "OPTIMIZE TABLE {$table[0]}" );
}
// 自動下書きを削除(30日以上前のもの)
$wpdb->query(
"DELETE FROM $wpdb->posts
WHERE post_status = 'auto-draft'
AND post_modified < DATE_SUB(NOW(), INTERVAL 30 DAY)"
);
} );
注意事項
- データベースの削除・最適化操作を行う前に必ずバックアップを取得してください。
wp db export backup.sqlでエクスポートできます。誤って必要なデータを削除した場合は復元できません。 OPTIMIZE TABLEはMyISAMテーブルでは断片化解消が行われますが、InnoDBテーブルでは実質的にはテーブルの再構築(REBUILD)が行われます。大きなテーブルに対しては実行中にDBロックが発生する場合があるため、トラフィックの少ない時間帯に実行してください。- 孤立したpostmetaやcommentmetaの削除は慎重に行ってください。プラグインが意図的に投稿なしでメタデータを保存している場合があります。削除後にプラグインの動作確認を行ってください。
まとめ
データベース最適化は「WP-CLIでDB状態確認→不要データ(リビジョン・Transient・ゴミ箱)削除→OPTIMIZE TABLEで断片化解消→インデックス追加でクエリ高速化→Cronで定期自動最適化」の流れで整備します。関連記事:WordPressの不要データを自動的に削除する方法、WordPressのリビジョン数を制限する方法。