【入門編】実務中級者向け:WP_Queryの「posts_where」フックで「LIKE」検索を「REGEXP」に置き換える際のパフォーマンスリスク – WordPress 内部コア・データベース構造とパフォーマンス最適化解析バイブル

こんにちは!WordPressの裏側の仕組みやデータベースとの対話に興味を持ってくれて嬉しいです。

普段何気なく使っている `WP_Query` ですが、私たちが「こんな条件で記事を取得したいな」とPHPで書いたコードは、内部で複雑なSQL文に変換されてMySQLへと投げられていますよね。

今回は、その中でも実務でよくある「`LIKE`検索を正規表現(`REGEXP`)に置き換える」というテクニックについて、その便利さと、背後にある恐ろしいパフォーマンスリスクについてお話していきます。

「他の言語や一般的なWebアプリケーション開発の経験はあるけれど、WordPressのデータベース周りはブラックボックスが多くて少し不安…」という中級者の方に向けて、データベースのインデックスの挙動から丁寧に解説していきますね。ここをクリアすれば、あなたも確実に一歩先を行くWordPressエンジニアになれますよ!

—

1. なぜ `LIKE` 検索を `REGEXP` に置き換えたくなるのか?

WordPressで特定のキーワードを含む投稿を検索するとき、基本的には `WP_Query` の `s` パラメータや、`meta_query` の `LIKE` 比較を使いますよね。

例えば、「apple」という単語をタイトルや本文から探す場合、SQLの内部では次のような `LIKE` 句が生成されます。

WHERE post_title LIKE ‘%apple%’

これはこれで動くのですが、実務の現場では次のような複雑な要求に直面することがあります。

  • 「`apple` または `orange` のいずれかを含む記事を一度に取得したい」
  • 「単語の境界を意識して、独立した `cat` という単語だけをヒットさせたい(`caterpillar` などの部分一致を除外したい)」
  • 「特定のパターン(例:3桁の数字から始まるタイトル)にマッチさせたい」

こういった複雑な条件を `LIKE` クエリだけで実現しようとすると、複数の条件を `OR` で何重にも繋ぐ必要があり、PHP側のコードが非常に煩雑になってしまいますよね。

そこで登場するのが、`posts_where` という強力なフックを使って、SQLの条件部分を丸ごと正規表現 (`REGEXP`) に書き換えるアプローチです。

—

2. 実装方法:`posts_where` フックを使った `REGEXP` への置き換え

まずは、実際にどうやって書き換えるのか、具体的なコードを見てみましょう。
ここでは、「タイトルに特定の単語のいずれかを含む投稿を取得する」というシチュエーションを想定しています。

/

  • WP_Query の WHERE 句を書き換えて REGEXP 検索を導入する例

/
function my_custom_posts_where_regex( $where, $query ) {
// 管理画面や、メインのクエリ以外では実行しないためのガード節(パフォーマンスの基本!)
if ( is_admin() || ! $query->is_main_query() ) {
return $where;
}

// カスタムクエリ変数 ‘my_regex_keyword’ が指定されている場合のみ処理する
$keyword_pattern = $query->get( ‘my_regex_keyword’ );
if ( ! empty( $keyword_pattern ) ) {
global $wpdb;

// セキュリティのため、入力値を適切にエスケープ・サニタイズする
// ※ここでは例としてプレースホルダーの代わりに安全な文字列を想定
$safe_pattern = esc_sql( $keyword_pattern );

// 通常の LIKE 条件を、REGEXP 条件に置き換える
// 例: ‘apple|orange’ のような正規表現パターンを想定
$where .= $wpdb->prepare( ” AND {$wpdb->posts}.post_title REGEXP %s”, $safe_pattern );
}

return $where;
}
add_filter( ‘posts_where’, ‘my_custom_posts_where_regex’, 10, 2 );

このコードのポイントと意味

1. ガード節(Guard Clause)
`is_admin()` や `! $query->is_main_query()` で、不要な管理画面やウィジェットの読み込み時にこの重い処理が走るのを防いでいます。これ、実務ではめちゃくちゃ重要な鉄則ですよ!
2. `posts_where` フィルター
WordPressが発行するSQLの `WHERE` 句の文字列そのものを、PHP側から直接書き換えることができるフックです。
3. `REGEXP` への置換
MySQLの `REGEXP` 演算子を使うことで、`’apple|orange’` のようにパイプ(`|`)で区切った複数のキーワードマッチングをたった1行の条件式で表現できるようになります。

一見すると、「スマートでなんて便利なんだ!」と感じますよね。ですが、ここからがエンジニアとしての腕の見せ所。この裏側に潜む重大なリスクについてお話しします。

—

3. 知られざるリスク:「フルテーブルスキャン」の罠

結論から言いますと、`REGEXP` を使うと、データベースに貼られたインデックス(Index)が一切効かなくなります。

データベースのインデックスが「本棚の索引(目次)」だとすると、`LIKE ‘abc%’` のような前方一致であれば、その索引を使って一瞬でお目当てのページを見つけることができます。

しかし、`REGEXP` や、前方一致ではない `LIKE ‘%abc’` のようなクエリを実行した場合、データベースは索引を使うことができなくなります。結果として、テーブルに保存されている数万、数百万行のデータをすべて1行ずつ上から順番に読み込んでチェックしていく「フルテーブルスキャン(全件走査)」を強制されることになるのです。

データの規模によるパフォーマンスの変化イメージ

[ データ数: 1,000件 ]
-> REGEXP使っても人間の体感ではほぼ分からないレベル (数ミリ秒)

[ データ数: 100,000件 (一般的な中規模メディアサイト) ]
-> 1回の検索でデータベースが重くなり、CPU使用率が跳ね上がる

[ データ数: 1,000,000件以上 (大規模ECやコミュニティサイト) ]
-> 複数ユーザーが同時に検索した瞬間、MySQLがダウン(スロークエリ・コネクション枯渇)

開発環境のローカルPC(データ数数十件)でテストしている時は「問題なく動いた!」となっても、本番環境の膨大なデータ量になった途端にサイト全体がスローダウンする……というのは、実務で本当によくある悲劇です。

—

4. それでも正規表現を使いたいときの代替案とベストプラクティス

「じゃあ、複雑な検索は諦めるしかないの?」いいえ、そんなことはありません。フルスペックの正規表現検索が必要な場合でも、プロのエンジニアは次のようなアプローチでリスクを最小化します。

① 対象のテーブルを絞り込む(プレフィルタリング)

`posts` テーブル全体に対して `REGEXP` をかけるのではなく、あらかじめカテゴリや投稿タイプ、日付などで十分に絞り込んだ少量のデータセットに対してのみ適用するようにします。

② WordPress標準の `meta_query` や `tax_query` を組み合わせる

可能な限り、インデックスが効く条件(投稿ID、投稿タイプ、タクソノミー関係など)を先に処理させ、どうしても必要な部分だけにカスタム条件を組み合わせる工夫をしましょう。

③ 本格的な全文検索エンジン(ElasticsearchやAlgoliaなど)の導入を検討する

もしメディアサイトやECサイトなどで、高度なあいまい検索や正規表現に近い柔軟なキーワード検索が必須なのであれば、WordPressのMySQLデータベースに直接頼るのではなく、外部の全文検索エンジンをインテグレートするのが、モダンなWebアーキテクチャにおける正解となります。

—

まとめ

今回は、`WP_Query` の `posts_where` フックを使った `REGEXP` 検索の利便性と、その裏にあるパフォーマンスリスクについて解説しました。

  • 便利さの代償: `REGEXP` は複雑な条件を簡潔に書ける反面、インデックスを無効化し、フルテーブルスキャンを引き起こす。
  • 環境による違い: 少量のデータでは気づきにくいが、データ量が増えるとサイト全体を巻き込むパフォーマンス低下の爆弾になる。
  • エンジニアの判断: 「本当にその正規表現検索はデータベースレベルでやるべきか?」を常に問いかけ、データ量や将来のスケールを見据えて設計する。

「ここをクリアすれば、WordPressの基本はバッチリマスターできますよ!」
データベースの挙動まで見据えたクエリチューニングができるようになると、どんな大規模案件でも自信を持って立ち向かえるようになります。ぜひ、ご自身の開発環境でも今日の話を意識してコードを見直してみてくださいね。

それでは、次のステップでも一緒に楽しくエンジニアリングを極めていきましょう!

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