こんにちは!WordPressの裏側の仕組みや、データベースがどう動いているのか気になって夜も眠れない時期、ありますよね。他のプログラミング言語からWordPressに入ってきた開発者ほど、「なんでこんなにテーブルの構造が独特なんだろう?」と驚くことが多いはずです。
今回は、WordPressのデータベーススキーマ、特に「隠れたインデックス(索引)」の整理と再構築という、一歩進んだパフォーマンス最適化の技術を一緒に見ていきましょう。
ここをクリアすれば、WordPressの内部構造に対する解像度がグッと上がり、現場で一目置かれるエンジニアに近づけますよ。それでは、さっそく本題に入っていきましょう!
—
1. なぜWordPressのデータベースは重くなるのか?
WordPressの心臓部であるMySQL/MariaDBデータベースには、お馴染みの `wp_posts` や `wp_postmeta` といったテーブルが存在します。
特にメタデータ(カスタムフィールドなど)を保存する `wp_postmeta` は、キーとバリューの組み合わせを何でも放り込める非常に柔軟な設計になっています。しかし、この柔軟性と引き換えに、データ量が増えてくるとクエリの実行速度がガタ落ちするという宿命を抱えています。
プラグインという名の「侵入者」たち
便利なプラグインをインストールするたび、彼らは勝手にデータベースへ新しい機能を追加します。その際、検索を速くしようとして独自のインデックス(索引)を勝手に作成することがよくあります。
イメージとしては、分厚い辞書のあちこちに、勝手に付箋をペタペタ貼っていくようなものです。付箋(インデックス)が多すぎると、以下の問題が発生します。
1. 読み取り(SELECT)は一瞬速くなるように見えても、管理が追いつかなくなる
2. 書き込み(INSERT / UPDATE / DELETE)のたびに、全ての付箋の貼り直し(インデックスの更新)が発生し、データベースが重くなる
3. MySQLのクエリプランナー(最適な実行計画を立てる頭脳)が、どのインデックスを使うべきか迷い、かえって処理が遅くなる
つまり、「不要なインデックスを掃除する」ことは、WordPressの書き込み性能を劇的に改善するための極めて有効なアプローチなんです。
—
2. 現在のインデックスを覗き見してみる
まずは、私たちのデータベースが今どうなっているのかを確認してみましょう。
以下のSQLクエリを、phpMyAdminやWP-CLIなどのデータベースクライアントから実行してみてください。
— wp_postmeta テーブルに現在貼られているインデックスを全て洗い出す
SHOW INDEX FROM wp_postmeta;
このコマンドを実行すると、次のような結果が返ってきます。
| Table | Non_unique | Key_name | Seq_in_index | Column_name | … |
| :— | :— | :— | :— | :— | :— |
| wp_postmeta | 0 | PRIMARY | 1 | meta_id | … |
| wp_postmeta | 1 | post_id | 1 | post_id | … |
| wp_postmeta | 1 | meta_key | 1 | meta_key | … |
| wp_postmeta | 1 | some_plugin_idx | 1 | meta_value | … |
- PRIMARY: 各行を一意に特定するための基本のインデックス(消しちゃダメなやつです)。
- post_id: どの投稿に紐づくメタデータかを探すための標準インデックス。
- meta_key: カスタムフィールドのキー名で検索するための標準インデックス。
- some_plugin_idx: ……おっと、見慣れないインデックスが混ざっていますね! これが、過去に入れたプラグインが残していった「隠れた不要インデックス」の可能性が高いものです。
—
3. 不要なインデックスを安全に削除し、再構築する
使われていないインデックスや、重複しているインデックスを特定したら、次は整理(ドロップ)です。
注意!絶対に消してはいけないコアのインデックス
WordPressのデフォルトで存在する以下のインデックスは絶対に削除しないでください。システムが完全に崩壊します。
- `wp_posts`: `PRIMARY`, `type_status_date`, `post_author`, `post_name` など
- `wp_postmeta`: `PRIMARY`, `post_id`, `meta_key`(MySQLの仕様上、`meta_key` はプレフィックスインデックスになっていることが多いです)
メンテナンス用の安全なSQL実行コード
もし、不要なプラグインが残していった `some_plugin_idx` を発見したら、次のように削除します。
— 不要になったカスタムインデックスを安全に削除する
— ※実行前には必ずデータベースのバックアップを取ってください!
DROP INDEX some_plugin_idx ON wp_postmeta;
たったこれだけです。これにより、データベースへの `INSERT`(記事の保存やカスタムフィールドの追加)時に走っていた無駄なインデックス更新コストが削減され、書き込み性能が嘘のように軽くなります。
—
4. 現場でありがちな「やらかし」と文法エラー
データベースを直接触るカスタマイズでは、ちょっとしたケアレスミスが致命傷になります。初心者の開発者が陥りがちな罠を確認しておきましょう。
罠1:バックアップを取らずに作業してしまう
「テスト環境だから大丈夫」と油断して本番さながらのSQLを流し、テーブル構造を破壊してしまうミスは後を絶ちません。作業前の `mysqldump` やホスティングのバックアップ機能の利用は絶対のルールです。
罠2:カラム名とインデックス名を混同する
インデックスを削除する際によくあるエラーがこちらです。
— 【誤ったコード例】カラム名を指定してしまっている
DROP INDEX post_id ON wp_postmeta;
— エラー: Table ‘wp_postmeta’ doesn’t exist in engine (またはインデックスが見つからない旨のエラー)
【正しい考え方】
`DROP INDEX` で指定するのは、カラム名ではなく「インデックスの名前(Key_name)」です。カラムを指定して削除したい場合は、インデックスそのものではなくテーブル定義の変更(`ALTER TABLE`)が必要になるため注意してくださいね。
正確な構文はこちらです。
— 正しいインデックス削除の構文
ALTER TABLE wp_postmeta DROP INDEX インデックス名;
—
まとめ:データベースの「健康診断」を習慣にしよういかがでしたでしょうか?
今回は、WordPressのデータベーススキーマにおける「隠れたインデックス」の整理とパフォーマンス最適化について解説しました。
- プラグインは勝手にインデックスを追加することがある
- インデックスが多すぎると、書き込み(INSERT/UPDATE)のパフォーマンスが低下する
- `SHOW INDEX` で現状を把握し、不要なものは `DROP INDEX` で整理する
- 作業前には必ずバックアップを取る!
ここをクリアできれば、単なる「WordPressの使い方を知っている人」から、「裏側の仕組みまでコントロールできるフルスタックエンジニア」への大きなステップアップになります。
定期的にデータベースの健康診断を行い、無駄のない美しいWordPress環境を保っていきましょう。あなたの開発ライフを応援しています!