閉じる

技術ブログ

【WP-CLI】10年物WordPressのDB掃除 ── 不要データを見つけて安全に消す方法

2026.03.31

WP-CLI 実践シリーズ #04
WordPressのDB掃除
10年分のゴミを安全に消す方法
「このテーブル、何のプラグインのだっけ?」
──履歴のないWordPressをリニューアルするための完全ガイド

10年以上運用されているWordPressのリニューアル(サーバ移転)。
引き継いだデータベースを開くと、見たこともないテーブルが何十個も。
wp_posts には知らない投稿タイプの記事が大量に残っている。
「このデータ、消していいの? 消したら壊れない?」

この記事では、不要データの見つけ方から安全な削除手順、そして最もクリーンな移行方法まで、Seeds Brainsの総力を挙げて徹底解説します。


1. なぜWordPressのDBは肥大化するのか

新規インストール直後のWordPressのデータベースは、わずか 12テーブル。しかし10年運用されたサイトでは100テーブル以上になっていることも珍しくありません。
なぜそうなるのか?原因は大きく4つあります。

1
プラグインの残骸
プラグインは独自テーブルを作成する。
「無効化」しただけではテーブルは消えない。
「削除(アンインストール)」しても、テーブルを消さないプラグインが多い。
2
投稿リビジョン
WordPressはデフォルトで記事の編集履歴を無制限に保存する。
1記事につき数十〜数百件のリビジョンが溜まっていく。
3
一時データ(Transient)
APIレスポンスのキャッシュ、プラグインの一時計算結果などが wp_options テーブルに溜まり続ける。
期限切れでも自動削除されないケースがある。
4
孤立データ
記事を削除しても、紐づいていた wp_postmeta(カスタムフィールド)や wp_term_relationships(カテゴリ紐付け)がそのまま残る

1-1. 典型的な「肥大化したDB」の姿

10年運用サイトのデータベースサイズ内訳(架空の例):

DB合計: 850MB
wp_posts(リビジョン含む)320MB(37.6%)
うちリビジョン: 240MB
wp_postmeta210MB(24.7%)
孤立メタ: 80MB
wp_options(Transient含む)95MB(11.2%)
Transient: 60MB
プラグイン由来テーブル(45個)180MB(21.2%)
不要: 120MB
その他(コアテーブル)45MB(5.3%)
必要なデータ
この例では、850MBのうち約500MB(60%)がゴミデータ。
クリーンアップ後は350MBまで縮小できる可能性があります。

2. ゴミを見つける ── DB調査の基本テクニック

まずは「何がゴミなのか」を特定する方法を学びましょう。WP-CLIとSQLを組み合わせて、データベースの全体像を把握します。

2-1. テーブル一覧と行数・サイズを確認する

最初にやるべきことは、いまDBにどんなテーブルがあるのかを全部出すことです。

# WP-CLIでテーブル一覧を表示
wp db tables

wp_commentmeta
wp_comments
wp_links
wp_options
wp_postmeta
wp_posts
wp_term_relationships
wp_term_taxonomy
wp_termmeta
wp_terms
wp_usermeta
wp_users
wp_actionscheduler_actions ← ?
wp_actionscheduler_claims ← ?
wp_actionscheduler_groups ← ?
wp_actionscheduler_logs ← ?
wp_wc_admin_notes ← ?
wp_wc_category_lookup ← ?
wp_yoast_indexable ← ?
wp_yoast_seo_links ← ?
wp_redirection_items ← ?
wp_redirection_logs ← ?

ポイント: WordPressのコアテーブルは 12個だけ。それ以外はすべてプラグインやテーマが作ったものです。
コアテーブル一覧は後述の「セクション3」で詳しく解説します。

テーブルの行数とサイズを一覧で見るには、SQLで確認するのが便利です:

# 各テーブルの行数とサイズを表示(大きい順にソート)
wp db query “SELECT
TABLE_NAME AS ‘テーブル名’,
TABLE_ROWS AS ‘行数’,
ROUND((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024, 2) AS ‘サイズ(MB)’
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE()
ORDER BY (DATA_LENGTH + INDEX_LENGTH) DESC;”

+————————————-+——–+————+
| テーブル名 | 行数 | サイズ(MB) |
+————————————-+——–+————+
| wp_postmeta | 485320 | 210.45 |
| wp_posts | 125840 | 318.72 |
| wp_options | 28450 | 95.33 |
| wp_actionscheduler_actions | 45200 | 52.18 |
| wp_yoast_indexable | 12800 | 28.44 |
| wp_wc_product_meta_lookup | 8500 | 18.22 |
| wp_comments | 3200 | 8.15 |
| wp_term_relationships | 15400 | 4.88 |
| … | | |
+————————————-+——–+————+

注目ポイント:
wp_postmeta が48万行もある場合、大半が孤立データの可能性が高い。
wp_options が2万8千行あるのも異常。通常は数百行程度。Transientが溜まっている証拠。
wp_actionscheduler_actions が4万5千行あるのは、WooCommerceやAction Schedulerのログが溜まっている。

2-2. WordPressのコアテーブル一覧(これだけが「正規の住民」)

以下の12テーブルが、WordPressが標準で使用するテーブルです。それ以外はすべてプラグインやテーマが追加したものです。

テーブル名 役割 重要度
wp_posts 投稿・固定ページ・メディア・リビジョンなど全コンテンツ 必須
wp_postmeta 投稿に紐づくメタ情報(カスタムフィールド) 必須
wp_comments コメント 必須
wp_commentmeta コメントのメタ情報 必須
wp_options サイト設定全般(siteurl, プラグイン設定, Transient) 必須
wp_users ユーザーアカウント 必須
wp_usermeta ユーザーのメタ情報(権限, プロフィール) 必須
wp_terms カテゴリ・タグなどの用語 必須
wp_termmeta タームのメタ情報 必須
wp_term_taxonomy タクソノミーとタームの関連付け 必須
wp_term_relationships 投稿とタームの関連付け 必須
wp_links ブログロール(リンク集、現在はほぼ未使用) 必須
判定ルール: テーブル名が wp_(接頭辞)+ 上記12個の名前 に該当しなければ、それはプラグインが作ったテーブルです。
(マルチサイトの場合は wp_2_posts のようにサイト番号が入ります)

3. 不要テーブルの特定 ── プラグインの残骸を見分ける

DBに知らないテーブルが大量にある。どれがどのプラグインのもので、どれが消していいのか?
テーブル名のパターンから元のプラグインを特定する方法を解説します。

3-1. よくあるプラグインのテーブルパターン

以下は、WordPress案件でよく遭遇するプラグイン由来テーブルの一覧です。プラグインが無効化・削除済みなら、これらは不要テーブルです。

テーブル名パターン 元のプラグイン 行数の目安
wp_actionscheduler_* Action Scheduler(WooCommerce等が依存) 数万〜数十万行
wp_wc_* / wp_woocommerce_* WooCommerce 商品数に比例
wp_yoast_* Yoast SEO 投稿数に比例
wp_aioseo_* All in One SEO 投稿数に比例
wp_redirection_* Redirection リダイレクト+ログ
wp_icl_* / wp_wpml_* WPML(多言語化) 言語数×投稿数
wp_statistics_* WP Statistics アクセスログ(巨大化しやすい)
wp_mailchimp_* MailChimp for WordPress 購読者数に比例
wp_cf7* / wp_db7_* Contact Form 7 + CFDB7 問い合わせ履歴
wp_nf3_* Ninja Forms フォーム送信履歴
wp_gf_* / wp_rg_* Gravity Forms フォーム送信履歴
wp_wpforms_* WPForms フォーム送信履歴
wp_ewwwio_* EWWW Image Optimizer 画像最適化履歴
wp_smush_* Smush(画像圧縮) 画像数に比例
wp_itsec_* iThemes Security セキュリティログ
wp_wfls_* / wp_wfhits Wordfence セキュリティスキャンログ(巨大化)
wp_slim_* Slimstat Analytics アクセスログ(巨大化しやすい)
wp_popularpostssummary WordPress Popular Posts PV集計データ
wp_e_* Elementor ページビルダーデータ
wp_revslider_* Revolution Slider スライダーデータ

3-2. 「これは何のテーブルだろう?」の調べ方

テーブル名から元のプラグインが推測できない場合の調べ方:

# テーブル名の接頭辞でGoogle検索する
# 例: wp_aelia_ というテーブルが見つかったら
# → 「wordpress plugin wp_aelia_ table」で検索

# テーブルの構造を見て、カラム名から推測する
wp db query “DESCRIBE wp_aelia_currencies;”

+—————–+———————+——+—–+
| Field | Type | Null | Key |
+—————–+———————+——+—–+
| id | bigint(20) unsigned | NO | PRI |
| currency_code | varchar(3) | NO | |
| rate | decimal(18,6) | YES | |
| is_active | tinyint(1) | NO | |
+—————–+———————+——+—–+

# → 「currency(通貨)」「rate(レート)」
# → 「Aelia Currency Switcher」プラグインだとわかる

もう一つの手がかり:
テーブルの CREATE TABLE 文のコメントに、プラグイン名やバージョンが書かれていることがあります。

wp db query "SHOW CREATE TABLE wp_aelia_currencies\G"

3-3. 現在有効なプラグインと照合する

# 現在インストールされているプラグイン一覧
wp plugin list –format=table

+—————————+———–+———–+
| name | status | version |
+—————————+———–+———–+
| advanced-custom-fields | active | 6.2.5 |
| contact-form-7 | active | 5.9.3 |
| wp-multibyte-patch | active | 2.9.1 |
| akismet | inactive | 5.3.1 |
+—————————+———–+———–+

# もし wp_yoast_* テーブルがあるのに Yoast SEO がリストにないなら
# → それは過去に使っていたプラグインの残骸 → 削除候補

不要テーブルの判定フロー
1 テーブル一覧を取得
wp db tables でDB内の全テーブルを列挙
2 コアテーブルを除外
12個のコアテーブルは必須。それ以外が調査対象
3 有効プラグインと照合
wp plugin list の結果と比較。有効プラグインのテーブルなら残す
4 残りが「削除候補」
プラグインが存在しないテーブル = 過去のプラグインの残骸。バックアップ後に DROP

4. 不要データの特定 ── テーブルの中のゴミ

テーブル単位の調査だけでは不十分です。コアテーブルの中にも大量のゴミが潜んでいます。
ここでは代表的な5種類のゴミデータとその見つけ方を解説します。

4-1. リビジョン(投稿の編集履歴)

リビジョンとは?

WordPressは記事を保存するたびに編集前の状態を自動で記録します。デフォルトでは保存回数に上限がなく、1記事で100件以上のリビジョンが溜まることもあります。
リビジョンは wp_posts テーブルに post_type = 'revision' として格納されています。

# リビジョンの数を確認
wp post list –post_type=revision –format=count

23847

# 2万3千件! これは多い。
# 公開記事が200件なのにリビジョンが2万件 → 1記事平均119件の履歴

# リビジョンが多い記事TOP10
wp db query “SELECT post_parent, COUNT(*) as cnt
FROM wp_posts
WHERE post_type = ‘revision’
GROUP BY post_parent
ORDER BY cnt DESC
LIMIT 10;”

+————-+—–+
| post_parent | cnt |
+————-+—–+
| 142 | 347 | ← この記事だけで347回保存された
| 58 | 289 |
| 215 | 198 |
| … | |
+————-+—–+

4-2. 自動下書き(Auto-Draft)とゴミ箱

自動下書きとは?

管理画面で「新規追加」をクリックしただけで、WordPressは自動的に空の下書き投稿を作成します。
書かずにページを離れると、この空の投稿がDBに残り続けます。
また、ゴミ箱に入れた投稿もデフォルトでは30日後に自動削除ですが、設定やバグで残ることがあります。

# 自動下書きの数を確認
wp post list –post_type=any –post_status=auto-draft –format=count

156

# ゴミ箱の投稿数を確認
wp post list –post_type=any –post_status=trash –format=count

89

4-3. 孤立したポストメタ(orphaned postmeta)

孤立メタとは?

投稿を削除しても、wp_postmeta テーブルに残っているメタデータのこと。
本来は投稿削除時にメタも一緒に消えるはずですが、直接SQLで消した場合プラグインの不具合で残ることがあります。
親のいないメタデータは完全に無意味なゴミです。

# 孤立したpostmetaの件数を確認
wp db query “SELECT COUNT(*) AS orphaned_meta
FROM wp_postmeta pm
LEFT JOIN wp_posts p ON pm.post_id = p.ID
WHERE p.ID IS NULL;”

+—————+
| orphaned_meta |
+—————+
| 48523 |
+—————+

# 4万8千件の孤立メタ!
# これは安全に削除できます(親投稿が存在しないので影響なし)

4-4. Transient(一時キャッシュデータ)

Transientとは?

プラグインやテーマが使う一時的なキャッシュデータ。wp_options テーブルに _transient__site_transient_ という名前で保存されます。
有効期限が過ぎても自動的には削除されないため、長期運用サイトでは数千〜数万件溜まります。

# Transientの件数を確認
wp db query “SELECT COUNT(*) AS transient_count
FROM wp_options
WHERE option_name LIKE ‘%_transient_%’;”

+——————+
| transient_count |
+——————+
| 12847 |
+——————+

# うち、期限切れのTransient
wp db query “SELECT COUNT(*) AS expired
FROM wp_options
WHERE option_name LIKE ‘_transient_timeout_%’
AND option_value < UNIX_TIMESTAMP();"

+———+
| expired |
+———+
| 9234 |
+———+

# 12,847件中9,234件が期限切れ → 安全に削除可能

4-5. 消えたカスタム投稿タイプのデータ

消えたカスタム投稿タイプとは?

以前のテーマやプラグインがカスタム投稿タイプ(例:portfoliotestimonialproduct)を登録していた場合、
テーマ変更やプラグイン削除後も、投稿データはDB内にそのまま残ります
管理画面には表示されないので、存在に気づきにくいのが厄介です。

# DB内に存在するすべての投稿タイプを確認
wp db query “SELECT post_type, COUNT(*) as cnt
FROM wp_posts
GROUP BY post_type
ORDER BY cnt DESC;”

+———————-+——-+
| post_type | cnt |
+———————-+——-+
| revision | 23847 |
| post | 205 |
| page | 42 |
| attachment | 1580 |
| nav_menu_item | 35 |
| auto-draft | 156 |
| wp_template | 12 |
| wp_template_part | 8 |
| portfolio | 48 | ← 現在未登録の可能性あり
| testimonial | 15 | ← 現在未登録の可能性あり
| product | 320 | ← WooCommerceを消した?
| shop_order | 1245 | ← WooCommerceの注文データ
| shop_coupon | 23 | ← WooCommerceのクーポン
+———————-+——-+

# 現在WordPressに登録されている投稿タイプと比較
wp post-type list –format=table

+———————+——————+
| name | label |
+———————+——————+
| post | 投稿 |
| page | 固定ページ |
| attachment | メディア |
| nav_menu_item | ナビゲーション |
| wp_template | テンプレート |
| wp_template_part | テンプレートパーツ|
+———————+——————+

# portfolio, testimonial, product, shop_order, shop_coupon は
# 現在のWordPressに登録されていない → 過去のテーマ/プラグインの残骸

注意: productshop_order はWooCommerceのデータです。
ECサイトとして運用していた過去がある場合、注文データ(shop_order)は法的に保管義務がある可能性があります(税務上7年間)。
削除前にお客様に必ず確認してください。

4-6. wp_options テーブルの異常な肥大化

wp_optionsの「正常値」を知っておく

wp_options テーブルの行数は、通常のWordPressサイトなら数百行程度です。
これが数千〜数万行になっている場合、ほぼ確実に異常データが溜まっています。
特に危険なのは、ECサイトで使われていたセッションデータ_wp_session_*)。
実際に300万行以上・600MBに膨れ上がった事例も報告されています。

# wp_options の行数と容量を確認
wp db query “SELECT COUNT(*) AS total_rows FROM wp_options;”

+————+
| total_rows |
+————+
| 28450 |
+————+

# → 2万8千行は明らかに異常

# option_nameのパターン別に件数を確認
wp db query “SELECT
CASE
WHEN option_name LIKE ‘_transient_%’ THEN ‘Transient’
WHEN option_name LIKE ‘_site_transient_%’ THEN ‘Site Transient’
WHEN option_name LIKE ‘_wp_session_%’ THEN ‘WP Session’
WHEN option_name LIKE ‘widget_%’ THEN ‘Widget’
WHEN option_name LIKE ‘cron’ THEN ‘Cron’
ELSE ‘Other’
END AS category,
COUNT(*) AS cnt,
ROUND(SUM(LENGTH(option_value)) / 1024 / 1024, 2) AS ‘size_MB’
FROM wp_options
GROUP BY category
ORDER BY cnt DESC;”

+—————-+——-+———+
| category | cnt | size_MB |
+—————-+——-+———+
| Transient | 12847 | 58.32 | ← ほぼ全部これ
| WP Session | 8420 | 24.15 | ← EC時代の残骸
| Site Transient | 3200 | 5.88 |
| Widget | 45 | 0.42 |
| Other | 3918 | 5.56 |
| Cron | 20 | 1.00 |
+—————-+——-+———+

4-7. 孤立したターム関連データ

# 孤立した term_relationships(投稿が削除されたが紐付けが残っている)
wp db query “SELECT COUNT(*) AS orphaned_relationships
FROM wp_term_relationships tr
LEFT JOIN wp_posts p ON tr.object_id = p.ID
WHERE p.ID IS NULL;”

+————————-+
| orphaned_relationships |
+————————-+
| 3842 |
+————————-+

# 使われていないターム(どの投稿にも紐付いていない)
wp db query “SELECT t.term_id, t.name, tt.taxonomy, tt.count
FROM wp_terms t
JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
WHERE tt.count = 0
ORDER BY tt.taxonomy;”


5. WP-CLIで安全にクリーンアップする

ゴミが特定できたら、いよいよ削除です。
絶対に守ること:最初にバックアップ。WP-CLIなら1コマンドです。

5-0. 【最重要】作業前のバックアップ

バックアップなしのDB操作は禁止。
どんなに「安全」と確信していても、予期しない依存関係や、気づいていないプラグインの参照がある可能性があります。
バックアップは保険ではなく、前提条件です。
# データベースの完全バックアップ
wp db export backup_before_cleanup_$(date +%Y%m%d).sql

Success: Exported to ‘backup_before_cleanup_20260408.sql’.

# ファイルサイズを確認(正常にエクスポートされたか)
ls -lh backup_before_cleanup_20260408.sql

-rw-r–r– 1 user group 850M Apr 8 10:00 backup_before_cleanup_20260408.sql

5-1. リビジョンの削除

# まず件数を確認
wp post list –post_type=revision –format=count

23847

# リビジョンを一括削除
wp post delete $(wp post list –post_type=revision –format=ids) –force

Success: Trashed post 98234.
Success: Trashed post 98233.

Success: Deleted 23847 of 23847 posts.

–force オプション:
--force をつけると、ゴミ箱を経由せず完全に削除します。
リビジョンはゴミ箱に入れる意味がないので、--force を推奨します。
リビジョンが大量にある場合(数万件〜)の注意:
$(wp post list --format=ids) がシェルの引数長制限に達することがあります。
その場合は、以下のようにバッチ処理します:

wp post delete $(wp post list --post_type=revision --format=ids --posts_per_page=500) --force
を何度か繰り返すか、SQLで直接削除します(後述)。

5-2. 自動下書きとゴミ箱の削除

# 自動下書きを削除
wp post delete $(wp post list –post_type=any –post_status=auto-draft –format=ids) –force

# ゴミ箱を空にする
wp post delete $(wp post list –post_type=any –post_status=trash –format=ids) –force

5-3. Transient(一時データ)の削除

# 期限切れのTransientだけを削除(安全)
wp transient delete –expired

Success: 9234 expired transients deleted from the database.

# すべてのTransientを削除(プラグインのキャッシュも含む)
# ※サイト表示が一時的に遅くなる可能性あり(再キャッシュされるまで)
wp transient delete –all

Success: 12847 transients deleted from the database.

Transientは削除しても壊れない:
Transientは「一時キャッシュ」なので、削除してもサイトが壊れることはありません
必要なキャッシュは、次のページ読み込み時に自動的に再生成されます。

5-4. 孤立したpostmetaの削除

# 孤立postmetaの削除(親投稿が存在しないメタデータ)
wp db query “DELETE pm FROM wp_postmeta pm
LEFT JOIN wp_posts p ON pm.post_id = p.ID
WHERE p.ID IS NULL;”

Query OK, 48523 rows affected (2.34 sec)

5-5. 孤立した term_relationships の削除

# 孤立した投稿-ターム紐付けの削除
wp db query “DELETE tr FROM wp_term_relationships tr
LEFT JOIN wp_posts p ON tr.object_id = p.ID
WHERE p.ID IS NULL;”

Query OK, 3842 rows affected (0.45 sec)

# ターム数のカウントを再計算(整合性を保つため)
wp term recount category
wp term recount post_tag

5-6. 不要テーブルの削除

# まず対象テーブルの中身をざっと確認(本当に不要か?)
wp db query “SELECT COUNT(*) FROM wp_yoast_indexable;”
wp db query “SELECT * FROM wp_yoast_indexable LIMIT 5;”

# 確信が持てたらDROP
wp db query “DROP TABLE wp_yoast_indexable;”
wp db query “DROP TABLE wp_yoast_seo_links;”

# 複数テーブルをまとめてDROPする場合
wp db query “DROP TABLE IF EXISTS
wp_redirection_items,
wp_redirection_logs,
wp_redirection_groups,
wp_redirection_404;”

DROP TABLE は取り消せない:
DROP TABLE は即座にテーブルを完全削除します。ゴミ箱もUNDOもありません。
必ずバックアップを取ってから実行してください。

5-7. データベースの最適化

# 大量のデータを削除した後は、ディスク領域を回収する
wp db optimize

+——————————+———-+———-+———-+
| Table | Op | Msg_type | Msg_text |
+——————————+———-+———-+———-+
| wordpress.wp_posts | optimize | status | OK |
| wordpress.wp_postmeta | optimize | status | OK |
| wordpress.wp_options | optimize | status | OK |
| … | | | |
+——————————+———-+———-+———-+
Success: Database optimized.

なぜ最適化が必要?
DELETE でデータを消しても、ディスク上のファイルサイズはすぐには縮まないことがあります(特にInnoDBエンジン)。
wp db optimize を実行することで、空き領域を回収し、実際にファイルサイズを縮小できます。

5-8. 便利なプラグイン・ツール

すべてをコマンドラインで行う必要はありません。以下のプラグインはGUI付きで安全にクリーンアップできます。

ツール名 種類 得意なこと 無料?
Advanced Database Cleaner WPプラグイン 孤立テーブル検出・不要データ一括削除。テーブルが現在のプラグインに属するか自動判定 基本無料
WP-Optimize WPプラグイン リビジョン・Transient・autoload最適化。スケジュール実行も可能 基本無料
WP Sweep WPプラグイン 孤立メタの検出・削除。種類ごとに件数を表示してから削除 無料
WP-CLI コマンドライン 最も柔軟。スクリプト化して繰り返し実行可能 無料
おすすめの使い分け:
初めてのクリーンアップ → Advanced Database Cleaner で全体像を把握 → WP-CLIで実行
定期メンテナンス → WP-Optimize のスケジュール機能で自動化
移行前の大掃除 → WP-CLIで一括処理(この記事の手順通り)

6. 目視確認の技術 ── phpMyAdminとWP-CLIの併用

「結局、目視で確認するしかないのか?」── 半分はYes、半分はNoです。
WP-CLIで効率的にあたりをつけ、phpMyAdminで細部を確認する。この2段階アプローチが最も実践的です。

6-1. WP-CLIで「あたりをつける」

# ①テーブル一覧 → コア以外を洗い出す
wp db tables

# ② wp_options の異常な行数を確認
wp db query “SELECT COUNT(*) FROM wp_options;”

# ③ autoload=’yes’ の重いオプションを確認
wp db query “SELECT option_name,
LENGTH(option_value) AS size_bytes,
autoload
FROM wp_options
WHERE autoload = ‘yes’
ORDER BY LENGTH(option_value) DESC
LIMIT 20;”

+———————————-+————+———-+
| option_name | size_bytes | autoload |
+———————————-+————+———-+
| rewrite_rules | 245832 | yes |
| widget_text | 128456 | yes |
| _transient_timeout_feed_ac0… | 89234 | yes |
| theme_mods_old-theme | 67891 | yes | ← 古いテーマの設定
| wpseo_taxonomy_meta | 45678 | yes | ← Yoast SEOの残骸
+———————————-+————+———-+

# ↑ autoload=’yes’ のオプションは毎回全ページで読み込まれる
# 不要なのにautoloadされているデータは、サイト速度を落とす原因

autoload について:
wp_options テーブルの autoload カラムが yes のデータは、すべてのページ読み込み時にメモリに展開されます。
古いテーマやプラグインの設定が autoload='yes' のまま残っていると、不要なメモリ消費の原因になります。

6-3. autoloadデータの健康診断

10年物のWordPressで最も見落とされがちなパフォーマンス問題が、wp_options の autoload です。
autoload=’yes’ のデータは毎回のページ読み込みで全件メモリに載るため、不要データが溜まるとサイト全体が遅くなります。

# autoloadデータの合計サイズを確認
wp db query “SELECT
ROUND(SUM(LENGTH(option_value)) / 1024 / 1024, 2) AS ‘autoload合計(MB)’
FROM wp_options
WHERE autoload = ‘yes’;”

+——————-+
| autoload合計(MB) |
+——————-+
| 8.45 |
+——————-+

# 8.45MB! 毎回のページ読み込みでこれがメモリに載っている

1MB未満
正常
1〜3MB
要注意
3〜5MB
要対策
5MB以上
緊急対応
# autoload=’yes’ で大きいオプションTOP20を確認
wp db query “SELECT
option_name,
ROUND(LENGTH(option_value) / 1024, 1) AS ‘サイズ(KB)’,
autoload
FROM wp_options
WHERE autoload = ‘yes’
ORDER BY LENGTH(option_value) DESC
LIMIT 20;”

+———————————–+———–+———-+
| option_name | サイズ(KB)| autoload |
+———————————–+———–+———-+
| rewrite_rules | 240.1 | yes | ← WordPress標準(正常)
| theme_mods_flavor | 128.4 | yes | ← 旧テーマの設定残骸
| widget_text | 89.2 | yes | ← 削除済みウィジェット?
| wpseo_taxonomy_meta | 67.8 | yes | ← Yoast SEOの残骸
| _transient_timeout_feed_ac0f2… | 45.3 | yes | ← 期限切れTransient
| flavor_customize_changeset | 34.7 | yes | ← 旧テーマの残骸
| flavor_sidebars | 28.9 | yes | ← 旧テーマの残骸
+———————————–+———–+———-+

# ↑ 現在使っていないテーマ「flavor」の設定が大量にautoloadされている!

よくある犯人:

  • 旧テーマの設定theme_mods_旧テーマ名)── テーマを変更しても旧テーマの設定は残る
  • 削除済みプラグインの設定wpseo_*, woocommerce_* 等)
  • 期限切れTransient_transient_*)── autoload=’yes’で残っていることがある
  • セッションデータ_wp_session_*)── ECサイトで数百万行に膨れることも
# 旧テーマの設定を削除する例
wp db query “DELETE FROM wp_options
WHERE option_name LIKE ‘theme_mods_flavor%’
OR option_name LIKE ‘flavor_%’;”

# 不要なオプションのautoloadをoffにする(削除が怖い場合)
wp db query “UPDATE wp_options
SET autoload = ‘no’
WHERE option_name = ‘wpseo_taxonomy_meta’;”

6-2. phpMyAdminで「細部を確認する」

WP-CLIではできない(やりにくい)こと:

テーブル構造をGUIで眺める
phpMyAdminの「構造」タブでカラム一覧を見れば、何のデータが入っているか直感的にわかる
データをスクロールして眺める
「表示」タブで実際のデータを見ると「あ、これは○○プラグインのデータだ」と気づけることが多い
シリアライズデータの中身
wp_optionsoption_value にあるシリアライズ文字列をコピーして unserialize() で中身を確認

6-4. ベストプラクティス:2つの画面を並べる

実務での推奨ワークフロー:

画面左: ターミナル(WP-CLI)── 数の確認、一括操作
画面右: phpMyAdmin ── データの中身を目視、テーブル構造の確認

WP-CLIで「このテーブル怪しいな」と当たりをつける → phpMyAdminで中身を開いて確認 → WP-CLIで削除
この流れが最も効率的です。


7. リニューアル時の最適な移行戦略

10年分のゴミを抱えたDBを、新しいサーバに移行する方法は大きく2つあります。
それぞれのメリット・デメリットを比較します。

方法A:データベース丸ごと移行(DB移行)

方法A: DB丸ごと移行
# 旧サーバーでエクスポート
wp db export full_backup.sql

# 新サーバーにインポート
wp db import full_backup.sql

# ドメイン変更
wp search-replace ‘old-domain.com’ ‘new-domain.com’

メリット
  • 完全にすべてのデータが移行される
  • プラグイン設定、ウィジェット、メニュー、ユーザーすべて維持
  • 手順がシンプルで失敗しにくい
デメリット
  • ゴミデータも丸ごと移行される
  • 事前にクリーンアップしないと新サーバーも肥大化
  • 不要テーブルも一緒についてくる

方法B:管理画面からエクスポート/インポート(コンテンツ移行)

方法B: エクスポート/インポート
# 管理画面の場合
# ツール → エクスポート → すべてのコンテンツ → XMLダウンロード
# ツール → インポート → WordPress Importer → XMLアップロード

# WP-CLIの場合
wp export –dir=./export/
wp import ./export/example.wordpress.2026-04-08.xml –authors=mapping.csv

メリット
  • コンテンツだけがクリーンに移行される
  • ゴミデータ・不要テーブルは一切持ち込まない
  • リニューアル後のDBが最小構成でスタートできる
  • 新しいテーマ・プラグイン構成でゼロから始められる
デメリット
  • プラグイン設定は移行されない(再設定が必要)
  • ウィジェット、メニュー、カスタマイザー設定は手動再現
  • ユーザーアカウントの移行に手間がかかる
  • ACF(Advanced Custom Fields)のフィールドグループは別途エクスポートが必要
  • メディアファイルのURL再マッピングが必要になることがある

方法C:ハイブリッド ── DB移行+クリーンアップ(推奨)

推奨: ハイブリッド方式

DBを丸ごと移行し、移行後にクリーンアップする。
これが実務で最も確実で、最もバランスの取れた方法です。

# ステップ1: 旧サーバーでフルバックアップ
wp db export full_backup.sql

# ステップ2: 新サーバーにインポート
wp db import full_backup.sql

# ステップ3: ドメイン置換
wp search-replace ‘old-domain.com’ ‘new-domain.com’

# ステップ4: 動作確認(この時点で全機能が動くことを確認)

# ステップ5: クリーンアップ(この記事のセクション5の手順を実行)
wp transient delete –all
wp post delete $(wp post list –post_type=revision –format=ids) –force
# … 孤立データの削除、不要テーブルのDROPなど

# ステップ6: 最適化
wp db optimize

なぜハイブリッドが推奨なのか?

方法A(DB丸ごと)だけだと → ゴミも全部持っていく
方法B(エクスポート)だけだと → プラグイン設定やウィジェットの再構築が大変
ハイブリッドなら → まず完全な状態で動くことを確認してから、不要なものだけ消す

特にリニューアルでは「まず動く状態を作ってから最適化」が鉄則です。

7-1. 方法Bが最適なケース

ただし、以下のケースではエクスポート/インポート(方法B)のほうが適切です:

テーマを完全に変更する
旧テーマの設定データが不要 → 記事だけ持っていけばOK
プラグイン構成を一新する
旧プラグインの設定が不要 → 新環境でゼロから設定したほうが速い
サイト構造を根本から変える
URLパーマリンク構造、カテゴリ体系を再設計 → 新規構築に近い

7-2. WP-CLIでのエクスポート/インポートの実践

# エクスポート(全コンテンツ)
wp export –dir=./export/

Starting export process…
Writing to file ./export/example.wordpress.2026-04-08.xml
Success: All done with export.

# 投稿タイプを指定してエクスポート(記事と固定ページだけ)
wp export –post_type=post,page –dir=./export/

# インポート(新サーバー側で実行)
# ※ WordPress Importer プラグインが必要
wp plugin install wordpress-importer –activate
wp import ./export/example.wordpress.2026-04-08.xml –authors=create

Importing post “会社概要”… done.
Importing post “サービス紹介”… done.
Importing attachment “logo.png”… fetching… done.

Success: Finished importing from ‘./export/example.wordpress.2026-04-08.xml’ file.

エクスポート/インポートの注意点:

  • メディアファイルは XMLに含まれるURLから自動ダウンロードされますが、旧サーバーが落ちていると取得できません。wp-content/uploads/ を別途コピーしておくこと。
  • ACFフィールドグループは「カスタムフィールド」→「ツール」→「エクスポート」で別途JSONエクスポートが必要です(WP-CLIなら wp acf export)。
  • 投稿IDが変わるため、ID直打ちしている箇所(ショートコード、テーマ内のハードコード)は修正が必要です。

8. 実践チェックリスト

最後に、10年物WordPressのリニューアル(サーバ移転)で使えるチェックリストをまとめます。

DB掃除チェックリスト
Phase 1: 調査(壊す前に現状把握)
1
バックアップ ── wp db export で完全バックアップ。ファイルサイズを確認
2
テーブル一覧 ── wp db tables で全テーブルを洗い出し、コアテーブルと比較
3
テーブルサイズ ── information_schema で各テーブルの行数・サイズを確認
4
有効プラグイン一覧 ── wp plugin list と非コアテーブルを突合
5
投稿タイプ一覧 ── DB内の post_typewp post-type list を比較
6
リビジョン数 ── wp post list --post_type=revision --format=count
7
Transient数 ── wp_options 内の _transient_ をカウント
8
孤立メタ ── LEFT JOIN で親のないpostmeta, termmeta, commentmetaを確認
Phase 2: クリーンアップ
9
リビジョン削除 ── wp post delete $(wp post list --post_type=revision --format=ids) --force
10
自動下書き/ゴミ箱削除 ── auto-draft, trash を削除
11
Transient削除 ── wp transient delete --all
12
孤立メタ削除 ── DELETE ... LEFT JOIN ... WHERE p.ID IS NULL
13
不要テーブル削除 ── プラグイン残骸テーブルを DROP TABLE
14
不要オプション削除 ── 古いテーマ・プラグインの wp_options レコードを削除
Phase 3: 仕上げ
15
DB最適化 ── wp db optimize
16
ターム再カウント ── wp term recount category
17
動作確認 ── 全ページの表示、管理画面の操作を確認
18
サイズ比較 ── クリーンアップ前後のDBサイズを比較して効果を記録

まとめ

Q. DBの不要データを見つける方法は?
→ WP-CLIとSQLを組み合わせて調査。コアテーブル12個以外はプラグイン由来。
wp db tableswp plugin list の突合が出発点。

Q. DBのテーブルやデータを目視で確認するしかない?
→ 「目視しかない」わけではない。WP-CLIで機械的にあたりをつけ、phpMyAdminで細部を確認する2段階アプローチが効率的。

Q. エクスポート/インポートで記事移行するのが結局一番良い?
→ 状況による。テーマ・プラグインを一新するなら方法B(エクスポート/インポート)が最もクリーン。
設定を維持したいなら方法C(DB丸ごと移行+クリーンアップ)が推奨。

10年分のゴミは、正しい手順で安全に片付けられる。
大事なのは「消す前に調べる」「消す前にバックアップ」。

作成: Seeds Brains(ジェイノーム業務支援AI)
WP-CLI 実践シリーズ #04 ── 2026年4月8日