【入門編】wp_postmetaのシリアライズされたデータに対するMySQL 5.7+ JSON型への移行と検索効率化 – WordPress 内部コア・データベース構造とパフォーマンス最適化解析バイブル

こんにちは。WordPressの深淵へようこそ。

WordPressのデータベース、特に `wp_postmeta` テーブルの構造に疑問を抱いたことはありますか?そう、あの「シリアライズされたデータ」の塊です。PHPの `serialize()` で保存された文字列を、MySQL側で検索しようとして `LIKE %…%` を使い、パフォーマンスをドブに捨ててしまった経験がある方も多いはずです。

今日は、WordPressの常識を覆し、MySQL 5.7+ の強力な武器である「JSON型」を活用して、WordPressの検索効率を劇的に改善する手法を伝授します。

—

なぜ「シリアライズ」は悪夢なのか?

WordPressの `wp_postmeta` は、EAV(Entity-Attribute-Value)モデルという非常に柔軟な構造をしています。しかし、配列やオブジェクトを `meta_value` に突っ込むとき、WordPressはそれをシリアライズ化して文字列として保存します。

// こんなデータが保存されているとします
$data = [‘price’ => 1000, ‘stock’ => 50];
update_post_meta($post_id, ‘product_info’, $data);
// DBの中身: a:2:{s:5:”price”;i:1000;s:5:”stock”;i:50;}

この文字列の中から「価格が1000以上の商品」を探そうとすると、MySQLはインデックスを使えず、テーブル全体をスキャン(フルスキャン)せざるを得ません。これが「WordPressが重い」と言われる原因の一つです。

—

解決策:MySQL JSON型への移行

MySQL 5.7から導入された `JSON` 型と、その専用関数を使うことで、このボトルネックを解消できます。

ステップ1:データ構造の変換

まず、PHP側でシリアライズされた文字列を `json_encode` に切り替えます。ただし、既存のデータを移行するには、DB内の文字列をパースしてJSONに変換するマイグレーションスクリプトが必要です。

ステップ2:JSON抽出と検索の高速化

MySQLの `->>` 演算子(インラインパス演算子)を使えば、JSON内の特定キーを抽出できます。

— 従来のLIKE検索(遅い!)
SELECT FROM wp_postmeta WHERE meta_value LIKE ‘%”price”;i:1000%’;

— JSON関数による検索(速い!)
— meta_valueがJSON型である場合
SELECT FROM wp_postmeta
WHERE CAST(meta_value->>’$.price’ AS UNSIGNED) >= 1000;

—

開発者が陥りやすい「文法エラー」と「罠」

この移行を進める際、多くの初学者が以下のポイントでつまづきます。

1. データ型の不整合: `meta_value->>’$.price’` は文字列を返します。比較演算子を使う際は、必ず `CAST()` や `CONVERT()` で型を合わせましょう。これを行わないと、暗黙的な型変換が発生し、インデックスが無視されることがあります。
2. パスの書き方: `$.key` の書き方を忘れないでください。JSONドキュメントのルート(`$`)から指定するのがMySQLのルールです。
3. WordPressの仕様との衝突: `get_post_meta` 関数は内部で `maybe_unserialize` を実行します。JSON型をそのまま扱うには、WordPressのAPIを介さず `$wpdb` で直接クエリを投げるか、カスタムDBクラスを作成してラップする必要があります。

—

実践:高速検索のためのインデックス活用

JSON型の真価は「仮想カラム(Generated Columns)」と組み合わせた時に発揮されます。特定のJSONキーに対してインデックスを張ることができるのです。

— meta_value内のpriceを抽出する仮想カラムを作成し、そこにインデックスを貼る
ALTER TABLE wp_postmeta
ADD COLUMN price_val INT AS (CAST(meta_value->>’$.price’ AS UNSIGNED)),
ADD INDEX (price_val);

こうすることで、数百万件のレコードがあっても、検索は一瞬で終わります。

—

まとめ:WordPressを掌握するということ

WordPressは「柔軟性」を優先するあまり、パフォーマンスを犠牲にしている部分が確かにあります。しかし、その内部構造を理解し、MySQLの最新機能を適切に組み合わせれば、WordPressはエンタープライズレベルの高速なシステムに化けます。

  • シリアライズは避ける: 新規開発時は可能な限り `json_encode` を使いましょう。
  • クエリの可視化: `EXPLAIN` コマンドで、自分の書いたクエリがフルスキャンしていないか確認する癖をつけてください。

ここをクリアすれば、あなたはもう「WordPressを使わされている」側から「WordPressを制御する」側のエンジニアです。ぜひ、現場のプロジェクトで試してみてください。

次は、クエリキャッシュの最適化について深掘りしましょうか。またお会いしましょう!

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