【入門編】実務中級者向け:SQLのEXPLAIN結果から読み解くWP_Queryのボトルネック特定法 – WordPress 内部コア・データベース構造とパフォーマンス最適化解析バイブル

WP_Queryの裏側を覗け:EXPLAINで紐解く「遅いSQL」の正体

WordPress開発者として一段上の領域へ足を踏み入れたいなら、`WP_Query`が裏側で吐き出しているSQLに目を向ける必要があります。

「記事が増えたらサイトが重くなった」という悩み。その原因の多くは、データベースのインデックスを無視した検索、つまりフルテーブルスキャンにあります。今日は、MySQLの`EXPLAIN`コマンドを使って、あなたの書いた`WP_Query`がデータベースにどのような負荷をかけているのか、その深淵を覗いてみましょう。

—

1. なぜ「遅い」が起きるのか?(イメージ図解)

データベースは巨大な「図書館」だと想像してください。

  • インデックスがある場合: 「索引(目次)」を使って、目的のページを一瞬で見つけます。
  • フルテーブルスキャン: 索引を使わず、「図書館のすべての本を最初から最後まで1冊ずつ確認する」状態です。

記事が1,000件程度なら誤差ですが、数万件を超えると、あなたのサーバーは悲鳴を上げます。`WP_Query`のパラメータ設定一つで、WordPressはこの「全検索」を強制させられてしまうことがあるのです。

—

2. ボトルネックを特定する魔法のコマンド `EXPLAIN`

まず、WordPressが発行しているSQLを確認しましょう。`SAVEQUERIES`定数を`wp-config.php`で有効にすると、`$wpdb->queries`から実行されたSQLを取得できます。

しかし、最も手っ取り早いのは、MySQLコンソールやphpMyAdminで直接SQLを投げ、先頭に`EXPLAIN`をつけることです。

— WP_Queryが発行したSQLの先頭に EXPLAIN をつける
EXPLAIN SELECT FROM wp_posts WHERE post_type = ‘product’ AND post_status = ‘publish’;

この結果出力される`type`カラムと`key`カラムに注目してください。

| type | key | rows | Extra |
| :— | :— | :— | :— |
| ALL | NULL | 50000 | Using where |

  • type = ALL: これが「フルテーブルスキャン」の警告音です。全行を舐めています。
  • key = NULL: インデックスが全く使われていません。
  • rows = 50000: 5万件全てをチェックしています。

—

3. よくある「罠」と修正の指針

実務でよく遭遇する「パフォーマンスを殺すクエリ」の代表例を見てみましょう。

罠:メタデータの不適切な検索

`meta_query`を多用すると、`wp_postmeta`テーブルとのJOINが発生します。もし対象の`meta_key`にインデックスが効いていない場合、クエリは壊滅的に遅くなります。

悪いコードの例:

$args = [
‘post_type’ => ‘post’,
‘meta_query’ => [
[
‘key’ => ‘event_date’, // ここにインデックスがないとフルスキャン確定
‘value’ => ‘2023-12-31’,
‘compare’ => ‘>’
]
]
];
$query = new WP_Query($args);

解決の極意:

1. インデックスの追加: `wp_postmeta`テーブルの`meta_key`と`meta_value`には標準でインデックスが貼られていますが、検索条件が複雑なら、カスタムテーブルへの切り出しを検討してください。
2. `suppress_filters`を賢く使う: 不必要なプラグインによるクエリ改変を防ぎます。
3. `no_found_rows`を意識する: ページネーション(`paged`)が不要なら、必ず `’no_found_rows’ => true` を指定してください。これだけで`SQL_CALC_FOUND_ROWS`という非常に重い処理がスキップされます。

—

4. 現場で使える「最適化」のチェックリスト

ここをクリアできれば、あなたのWordPressは別次元の速さになります。

  • [ ] `no_found_rows` は適切か?(ページネーション不要なら必ずtrueに)
  • [ ] `fields` パラメータを活用しているか?(`’fields’ => ‘ids’` とすれば、オブジェクト全体をロードせずIDのみを取得でき、メモリ消費を劇的に抑えられます)
  • [ ] `EXPLAIN` で `type` が `ref` または `eq_ref` になっているか?(`ALL`になっていたら再考の余地ありです)
  • [ ] 不要なJOINを避けているか?(`WP_Query`のパラメータで解決できない複雑な検索は、独自SQL+`wp_cache_set`でのキャッシュ運用を検討しましょう)

—

まとめ:WordPressの「中」を知れば怖くない

WordPressは「遅い」と言われがちですが、それは多くの場合、開発者がデータベースの挙動を無視してクエリを投げていることが原因です。

`WP_Query`をただの便利な関数として使うのではなく、「今、MySQLに対してどんな命令を送っているのか?」を常に想像してください。`EXPLAIN`の結果を読み解き、インデックスの貼られたクエリを組み立てる。それが、WordPressを掌握するエンジニアへの第一歩です。

ここをマスターすれば、どんなに大規模なサイトでも余裕を持って設計できるようになりますよ。一緒に、最高に効率的なWordPressの世界を突き詰めましょう!

タイトルとURLをコピーしました