2026年5月20日
2026年5月20日
WordPressのデータベースを最適化する方法
はじめに
WordPressを長期間運用するとデータベースに不要なデータが蓄積し、クエリ速度が低下します。リビジョン・スパムコメント・期限切れtransient・孤立したメタデータを定期的に削除することで、データベースのサイズ削減とクエリ高速化が実現できます。
症状・原因
- データベースのサイズが数GBに膨れ上がっている
- 管理画面の動作が重くなってきた
- wp_optionsテーブルが大きくなっている
- MySQLのスロークエリログに長時間クエリが記録されている
解決手順
ステップ1:データベースの現状を確認する
# データベースサイズの確認
wp db size
# テーブルごとのサイズ確認
wp db size --tables
# 詳細情報(フラグメント等)
wp db query "SELECT table_name, data_length/1024/1024 AS data_mb,
index_length/1024/1024 AS index_mb,
data_free/1024/1024 AS free_mb
FROM information_schema.tables
WHERE table_schema = DATABASE()
ORDER BY (data_length + index_length) DESC;"
ステップ2:不要データを一括削除する
# リビジョンの削除(全記事の過去編集履歴)
wp post delete $(wp post list --post_type=revision --format=ids) --force
# スパムコメントの削除
wp comment delete $(wp comment list --status=spam --format=ids) --force
# ゴミ箱の記事を削除
wp post delete $(wp post list --post_status=trash --format=ids) --force
# 期限切れtransientを削除
wp transient delete --expired
# 孤立したメタデータを削除(投稿に紐付かないpostmeta)
wp db query "DELETE pm FROM wp_postmeta pm
LEFT JOIN wp_posts p ON p.ID = pm.post_id
WHERE p.ID IS NULL;"
# 孤立したコメントメタを削除
wp db query "DELETE cm FROM wp_commentmeta cm
LEFT JOIN wp_comments c ON c.comment_ID = cm.comment_id
WHERE c.comment_ID IS NULL;"
ステップ3:リビジョン数を制限する
// wp-config.php: リビジョンの最大数を設定
// リビジョンを無効化する場合
define('WP_POST_REVISIONS', false);
// リビジョン数を制限する場合(3世代まで保持)
define('WP_POST_REVISIONS', 3);
// 自動保存の間隔を延ばす(デフォルト60秒)
define('AUTOSAVE_INTERVAL', 300); // 5分
// functions.php: 古いリビジョンを定期削除
add_action('wp_scheduled_delete', function (): void {
global $wpdb;
// 30日以上前のリビジョンを削除
$wpdb->query(
"DELETE p, pm FROM {$wpdb->posts} p
LEFT JOIN {$wpdb->postmeta} pm ON pm.post_id = p.ID
WHERE p.post_type = 'revision'
AND p.post_date < DATE_SUB(NOW(), INTERVAL 30 DAY)"
);
});
ステップ4:wp_optionsテーブルを最適化する
# autoloadされているオプションのサイズを確認
wp db query "SELECT option_name, length(option_value) as size
FROM wp_options
WHERE autoload = 'yes'
ORDER BY size DESC
LIMIT 20;"
# 不要なtransientを削除(transientはoption_nameに _transient_ が含まれる)
wp db query "DELETE FROM wp_options
WHERE option_name LIKE '_transient_%'
OR option_name LIKE '_site_transient_%';"
# autoloadの重いオプションをno-autoloadに変更(使用頻度の低いもの)
# wp option update [option_name] --autoload=no は対象を調査してから実施
ステップ5:テーブルを最適化してフラグメントを解消する
# WP-CLI でテーブル最適化
wp db optimize
# または個別テーブルを指定
wp db query "OPTIMIZE TABLE wp_posts, wp_postmeta, wp_options, wp_comments;"
# 自動最適化スクリプト(cronで月1回実行)
#!/bin/bash
WP_PATH="/var/www/html"
# 不要データ削除
wp --path="$WP_PATH" post delete \
$(wp --path="$WP_PATH" post list --post_type=revision --format=ids) --force 2>/dev/null
wp --path="$WP_PATH" transient delete --expired
# テーブル最適化
wp --path="$WP_PATH" db optimize
echo "Database optimization completed: $(date)"
# crontab: 月1回データベース最適化
0 3 1 * * /bin/bash /scripts/db_optimize.sh >> /var/log/db_optimize.log 2>&1
注意事項
- リビジョンを削除する前にバックアップを取ってください。削除したリビジョンは復元できません
OPTIMIZE TABLEはMyISAMテーブルに最も効果的です。InnoDBではALTER TABLE ... ENGINE=InnoDBが同等の効果を持ちます- wp_optionsの
autoload=yesを安易に変更するとサイトが壊れる可能性があります。変更前に該当オプションが何に使われているか確認してください
まとめ
wp post delete でリビジョン・ゴミ箱を削除し、wp transient delete --expired で期限切れtransientを削除します。wp-config.php で WP_POST_REVISIONS を3〜5に制限して新たなリビジョン蓄積を防ぎます。月1回cronで wp db optimize を実行してテーブルのフラグメントを解消します。