技術ブログ
【WP-CLI】10年物WordPressのDB掃除 ── 不要データを見つけて安全に消す方法
10年以上運用されているWordPressのリニューアル(サーバ移転)。
引き継いだデータベースを開くと、見たこともないテーブルが何十個も。
wp_posts には知らない投稿タイプの記事が大量に残っている。
「このデータ、消していいの? 消したら壊れない?」
この記事では、不要データの見つけ方から安全な削除手順、そして最もクリーンな移行方法まで、Seeds Brainsの総力を挙げて徹底解説します。
1. なぜWordPressのDBは肥大化するのか
新規インストール直後のWordPressのデータベースは、わずか 12テーブル。しかし10年運用されたサイトでは100テーブル以上になっていることも珍しくありません。
なぜそうなるのか?原因は大きく4つあります。
「無効化」しただけではテーブルは消えない。
「削除(アンインストール)」しても、テーブルを消さないプラグインが多い。
1記事につき数十〜数百件のリビジョンが溜まっていく。
wp_options テーブルに溜まり続ける。期限切れでも自動削除されないケースがある。
wp_postmeta(カスタムフィールド)や wp_term_relationships(カテゴリ紐付け)がそのまま残る。1-1. 典型的な「肥大化したDB」の姿
10年運用サイトのデータベースサイズ内訳(架空の例):
wp_posts(リビジョン含む)320MB(37.6%)
wp_postmeta210MB(24.7%)
wp_options(Transient含む)95MB(11.2%)
クリーンアップ後は350MBまで縮小できる可能性があります。
2. ゴミを見つける ── DB調査の基本テクニック
まずは「何がゴミなのか」を特定する方法を学びましょう。WP-CLIとSQLを組み合わせて、データベースの全体像を把握します。
2-1. テーブル一覧と行数・サイズを確認する
最初にやるべきことは、いまDBにどんなテーブルがあるのかを全部出すことです。
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 ← ?
…
コアテーブル一覧は後述の「セクション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. 「これは何のテーブルだろう?」の調べ方
テーブル名から元のプラグインが推測できない場合の調べ方:
# 例: 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 がリストにないなら
# → それは過去に使っていたプラグインの残骸 → 削除候補
wp db tables でDB内の全テーブルを列挙wp plugin list の結果と比較。有効プラグインのテーブルなら残す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で消した場合やプラグインの不具合で残ることがあります。
親のいないメタデータは完全に無意味なゴミです。
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(一時キャッシュデータ)
プラグインやテーマが使う一時的なキャッシュデータ。wp_options テーブルに _transient_ や _site_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. 消えたカスタム投稿タイプのデータ
以前のテーマやプラグインがカスタム投稿タイプ(例:portfolio、testimonial、product)を登録していた場合、
テーマ変更やプラグイン削除後も、投稿データは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に登録されていない → 過去のテーマ/プラグインの残骸
product や shop_order はWooCommerceのデータです。ECサイトとして運用していた過去がある場合、注文データ(shop_order)は法的に保管義務がある可能性があります(税務上7年間)。
削除前にお客様に必ず確認してください。
4-6. wp_options テーブルの異常な肥大化
wp_options テーブルの行数は、通常のWordPressサイトなら数百行程度です。
これが数千〜数万行になっている場合、ほぼ確実に異常データが溜まっています。
特に危険なのは、ECサイトで使われていたセッションデータ(_wp_session_*)。
実際に300万行以上・600MBに膨れ上がった事例も報告されています。
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. 孤立したターム関連データ
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. 【最重要】作業前のバックアップ
どんなに「安全」と確信していても、予期しない依存関係や、気づいていないプラグインの参照がある可能性があります。
バックアップは保険ではなく、前提条件です。
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 を推奨します。$(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(一時データ)の削除
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は「一時キャッシュ」なので、削除してもサイトが壊れることはありません。
必要なキャッシュは、次のページ読み込み時に自動的に再生成されます。
5-4. 孤立した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 は即座にテーブルを完全削除します。ゴミ箱も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されているデータは、サイト速度を落とす原因
wp_options テーブルの autoload カラムが yes のデータは、すべてのページ読み込み時にメモリに展開されます。古いテーマやプラグインの設定が
autoload='yes' のまま残っていると、不要なメモリ消費の原因になります。6-3. autoloadデータの健康診断
10年物のWordPressで最も見落とされがちなパフォーマンス問題が、wp_options の autoload です。
autoload=’yes’ のデータは毎回のページ読み込みで全件メモリに載るため、不要データが溜まるとサイト全体が遅くなります。
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! 毎回のページ読み込みでこれがメモリに載っている
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ではできない(やりにくい)こと:
wp_options の option_value にあるシリアライズ文字列をコピーして unserialize() で中身を確認6-4. ベストプラクティス:2つの画面を並べる
画面左: ターミナル(WP-CLI)── 数の確認、一括操作
画面右: phpMyAdmin ── データの中身を目視、テーブル構造の確認
WP-CLIで「このテーブル怪しいな」と当たりをつける → phpMyAdminで中身を開いて確認 → WP-CLIで削除
この流れが最も効率的です。
7. リニューアル時の最適な移行戦略
10年分のゴミを抱えたDBを、新しいサーバに移行する方法は大きく2つあります。
それぞれのメリット・デメリットを比較します。
方法A:データベース丸ごと移行(DB移行)
wp db export full_backup.sql
# 新サーバーにインポート
wp db import full_backup.sql
# ドメイン変更
wp search-replace ‘old-domain.com’ ‘new-domain.com’
- 完全にすべてのデータが移行される
- プラグイン設定、ウィジェット、メニュー、ユーザーすべて維持
- 手順がシンプルで失敗しにくい
- ゴミデータも丸ごと移行される
- 事前にクリーンアップしないと新サーバーも肥大化
- 不要テーブルも一緒についてくる
方法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を丸ごと移行し、移行後にクリーンアップする。
これが実務で最も確実で、最もバランスの取れた方法です。
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)のほうが適切です:
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のリニューアル(サーバ移転)で使えるチェックリストをまとめます。
wp db export で完全バックアップ。ファイルサイズを確認wp db tables で全テーブルを洗い出し、コアテーブルと比較information_schema で各テーブルの行数・サイズを確認wp plugin list と非コアテーブルを突合post_type と wp post-type list を比較wp post list --post_type=revision --format=countwp_options 内の _transient_ をカウントLEFT JOIN で親のないpostmeta, termmeta, commentmetaを確認wp post delete $(wp post list --post_type=revision --format=ids) --forcewp transient delete --allDELETE ... LEFT JOIN ... WHERE p.ID IS NULLDROP TABLEwp_options レコードを削除wp db optimizewp term recount category 等Q. DBの不要データを見つける方法は?
→ WP-CLIとSQLを組み合わせて調査。コアテーブル12個以外はプラグイン由来。
wp db tables と wp plugin list の突合が出発点。
Q. DBのテーブルやデータを目視で確認するしかない?
→ 「目視しかない」わけではない。WP-CLIで機械的にあたりをつけ、phpMyAdminで細部を確認する2段階アプローチが効率的。
Q. エクスポート/インポートで記事移行するのが結局一番良い?
→ 状況による。テーマ・プラグインを一新するなら方法B(エクスポート/インポート)が最もクリーン。
設定を維持したいなら方法C(DB丸ごと移行+クリーンアップ)が推奨。
10年分のゴミは、正しい手順で安全に片付けられる。
大事なのは「消す前に調べる」「消す前にバックアップ」。
WP-CLI 実践シリーズ #04 ── 2026年4月8日