GeoDirectory

Advanced Custom Fields はスケールしない

Advanced Custom Fields は、数百万人に利用されている優れたプラグインで、WordPressをフルスタックCMSへと変貌させ、無制限のカスタムフィールドグループやタイプを作成し、あらゆる種類のカスタム投稿タイプに追加することができます。

しかし、Advanced Custom Fieldsのスケーラビリティの限界についてはあまり知られていません。

GeoDirectoryがリスティングのカスタムフィールド管理にAdvanced Custom Fieldsを使用しているかどうか、よく質問を受けます。

GeoDirectoryには独自のカスタムフィールドシステムが搭載されていると答えると、なぜ「車輪の再発明」をしたのかと疑問を持たれます。

私たちにとって答えは明白で、Advanced Custom Fieldsのスケーラビリティはディレクトリ構築においてかなり限界があります。

しかし、ユーザーとして利用している方々は、内部で何が起きているか、そしてウェブディレクトリが抱えるスケーラビリティの課題を把握していないのかもしれないと考えました。

そんな折、あるところで投票を見かけました。それは Facebookの人気WordPressグループで行われていたもので、「最高のディレクトリ」に投票する選択肢には、GeoDirectory、人気マーケットプレイスで入手できるいくつかのディレクトリテーマ、そしてACF + FacetWP.

という選択肢もありました。結果を見て私たちは驚きを隠せませんでした。ACF + FacetWPが予想をはるかに上回る票を獲得していたのです。

投票した方々は一般ユーザーではなく、ウェブ開発者やWordPressの専門家であるはずでした。

そこで、ディレクトリにAdvanced Custom Fieldsを使うべきではない理由を説明する時が来たと判断しました。

また、顧客に対して高速でスケーラブルな、持続的な成長が可能なソリューションを提供することを重視しないWeb開発者でない限り、そのソリューションを誰にも提案すべきでない理由についても説明します。

WordPressカスタムフィールドのスケーラビリティの限界

WordPressはデフォルトで、カスタムフィールドのデータをwp_postmetaデータベーステーブルに保存しており、投稿内で使用されるカスタムフィールドごとに1行が作成されます。

それに加えて、WordPressは各投稿についてこのテーブルに多くの追加データを書き込み、それぞれがテーブルの1行を使用します。

SQLクエリの最適化に時間をかけたことがある方なら、ディレクトリやフィルタリングのような用途にとって、それが理想的な状況ではないことはよくご存じでしょう。

実際、デフォルトのデータベース構造は、多数の投稿やカスタムフィールドを持つウェブサイトにとって、大きなボトルネックになる可能性があります。

これはWordPressの弱点の一つとされています。

カスタムフィールドで投稿をフィルタリングするには、クエリ内でwp_postテーブルとwp_postmetaテーブルを結合しなければならないからです。

テーブルが大きくなればなるほど、クエリは遅くなります。

さらに最悪なのは、2つのメタ値でフィルタリングしたい場合、1つのクエリで処理するにはpost_metaテーブルを2回結合する必要があることです。

これはシステムメモリを消費し、小規模なディレクトリ以外では処理速度を著しく低下させる可能性があります。

Advanced Custom Fieldsのスケーラビリティの限界

Advanced Custom Fieldsプラグインは、投稿数・ページ数・カスタムフィールド数が少ないまたは中程度のウェブサイトには最適です。

しかし、ごく一部の例外を除き、ディレクトリはまさにその逆です。

ディレクトリは非常に多くの投稿を持ち、カスタムフィールドの数も膨大になる可能性があります。

Advanced Custom Fieldsのスケーラビリティにおける主な問題は、リスティングに追加されたカスタムフィールドごとに、データベースのwp_postmetaテーブルに2行が作成されることです。

また、プラグイン自身の設定に関するpostmetaの行もいくつか追加されます。

つまり、デフォルトのWordPressカスタムフィールドシステムを使用する場合と比べて、データベースのwp_postmetaテーブルに2倍以上の行が追加されることになります。

この問題をより分かりやすく説明するために、簡単なテストを行いました。

新しいWordPressウェブサイトを作成し、「Hello World」投稿とサンプルページを削除した上で、Advanced Custom Fieldsをインストールしました。

1つのグループと5つのカスタムフィールドを作成し、その5つのカスタムフィールドを使用した投稿を3件公開しました。

この時点で、wp_postmetaテーブルにはすでに83行が存在していました。

これは驚異的な数字です。

300,000件のリスティングと5つのカスタムフィールドを持つディレクトリでは、一体何行になるか想像してみてください。

ACFを使用すると、wp_postmetaテーブルの行数は最低でも3,000,000行になります

GeoDirectoryはどのようにスケールするのか?

とてもシンプルです。カスタム投稿タイプごとに専用のカスタムテーブルを作成しています。

例:wp_gd_gd_place_detail

このテーブルには、すべてのカスタムフィールドとそのデータを、投稿ごとに1行で保存しています。

また、WordPressがデフォルトのwpデータベーステーブルを操作するための独自のPHP APIを持つように、私たちもカスタムテーブルを操作するための独自のPHP APIを構築しました。

つまりGDは、ほとんどの場合、投稿テーブルと自社テーブルをJOINするだけで済みます。

その結果、任意のカスタムフィールドで結果をフィルタリングできます。

たとえば20個のカスタムフィールドでフィルタリングする場合、ACFではfacetWP(処理を高速化しますが、コアの制限は残ります)を使っても、1つのクエリで同じ処理を行うために複数のテーブルを何度もJOINする必要があり、同じクエリに対して何倍ものサーバーメモリを消費します。

まとめ

GeoDirectoryをWordPressまたはWP + Advanced Custom Fieldsと比較すると、次のことがわかります:

WordPress
1) フィルタリングしたいカスタムフィールドごとに、追加のテーブルJOINが必要になる。
2) wp_postmetaはすぐに肥大化し、クエリの速度が低下する

WP + ACF

1) フィルタリングしたいカスタムフィールドごとに、追加のテーブルJOINが必要になる。
2) wp_postmetaのサイズがWordPress単体と比べて2倍になる

GeoDirectory

1) JOINは不要
2) GDはwp_postmetaに情報を追加しないため、不要な肥大化が生じない。
3) 掲載情報を保存するデータベースは、投稿ごとに1行のみカウントする

WordPressはデータの保存方法にこの制限があることで知られています。ほとんどの場合、このシステムは問題なく機能しますが、大規模なディレクトリとなると、適切なソリューションとは言えません。

だからこそGeoDirectoryを使えば、数百万件の掲載情報を持つディレクトリを作成できます。一方、WP + Advanced Custom Fieldsでは、深刻なパフォーマンス問題が現れ始める前に作れるディレクトリは、せいぜい数百件止まりでしょう。

これらは、GeoDirectoryにAdvanced Custom Fieldsを使用しないと決めた理由となるスケーラビリティの限界であり、あなたも使用すべきでない理由です。

ご質問があれば、下のコメント欄でお気軽にどうぞ。