PaPoo
cover
technews
Author
technews
世界の技術ニュースをリアルタイムでキャッチし、日本語でわかりやすく発信。AI・半導体・スタートアップから規制動向まで、グローバルテックシーンの「今」をお届けします。

PlanetScaleがPostgres向け全文検索「TIN」を出した理由

PlanetScaleが、Postgres向けの全文検索拡張「TIN」をGAとして公開した。検索エンジンというと専用プロダクトを思い浮かべがちだが、今回の話は「Postgresの中でどこまで実用的な全文検索をやれるのか」に踏み込んでいる。しかも単なる追加機能ではなく、更新が続く本番DBで検索を走らせる前提にかなり強く寄せているのが面白い。この記事では、その主張とベンチマークの見せ方がかなりはっきりしている。

TINはPostgresの中で全文検索を完結させるための拡張だった

PlanetScaleは、顧客から最もよく求められるPostgres機能のひとつが全文検索だとして、TINを発表した。TINは “Text INdex” の略で、PostgresとNekiの両方で使える全文検索拡張としてGA扱いになっている。使い方は素直で、CREATE INDEX ... USING tin(...) でインデックスを作り、==> 演算子で検索する。元記事では、商品説明から「stretch denim jeans」を含む上位10件を返す例、メール本文から特定の語を含む文書を拾う例、写真のタグの件数を数える例が示されていた。

PlanetScaleがTINに求めた条件はかなり厳しい。Boolean検索、phrase query、span query を扱え、fuzzy検索やワイルドカード、正規表現にも対応し、case folding と accent folding も必要だという。さらに COUNT(*) と BM25 でのtop-k検索も必要で、しかも更新・削除・挿入が走る本番DBの中で、join や複雑なWHERE句、レプリケーション、バックアップ、トランザクション可視性まで壊さずに動かさなければならない。既存のPostgres向け全文検索インデックスは少なくとも3つあるが、その要件を全部満たすものはなかった、と記事は断言している。

性能面の主張も強い。ベンチマークにはStack Exchange由来の85GB、1億5000万文書のコーパスを使い、2〜15語の断片を組み合わせた1,719件の合成クエリを投げた。実行環境はAWSのi7i.8xlarge、Postgres 18.6を8 vCPU・32GB RAMに制限したコンテナで動かしている。比較対象はTIN v1.0.2、ParadeDB v0.25.2、pg_textsearch v1.4.0、そしてPostgres標準のGINだ。インデックス構築では、TINが8分10秒で50.7GB、ParadeDBが19分20秒で52.1GB、pg_textsearchが26分49秒で41.5GB、GINが2時間9分4秒で28.0GBだった。

検索結果では差はもっと大きい。混在クエリのtop-10検索では、TINはParadeDBの25倍のQPSを出し、p99レイテンシは26分の1だった。conjunctionとphraseのtop-10検索では、TINはParadeDBの10倍、GINの541倍のQPSで、p99はそれぞれ6分の1、1356分の1とされた。さらに更新を同時に流すdisjunction検索では、TINがpg_textsearchの36倍、ParadeDBの57倍のQPSを出し、10分間で271,398件の更新をこなした。ParadeDBは193,487件、pg_textsearchは735件にとどまった。記事は、pg_textsearchは読者のトラフィックが書き込みロックを奪ってしまい、数秒で更新が詰まると説明している。

加えて、インデックスがメモリに収まる条件でもTINは強かった。Wikipediaコーパスでのdisjunctionの COUNT(*) では、TINが10,260 QPS・p99 2msだったのに対し、ParadeDBは291 QPS・95ms、Postgres GINは1.4 QPS・30,292msだった。全文検索は「速いか遅いか」だけでなく、ディスクやブロックキャッシュをどれだけ食うかも重要だが、TINは1クエリあたりの読み出し量が小さいことも繰り返し示されている。

まず強く感じたのは、全文検索を“別物”にしたくないという思想

この記事で一番はっきりしているのは、PlanetScaleがTINを「検索専用システムの代用品」ではなく、「Postgresの中に置いておける全文検索」として売っていることだと思う。検索だけ速くても、更新が遅かったり、トランザクションの整合性が怪しかったり、複雑なWHERE句と組み合わせに弱かったりすると、本番ではすぐに使いづらくなる。そこを最初から条件に入れているのは筋がいい。実際、記事が派手なQPSだけでなく、更新同時実行や COUNT(*)、メモリに収まるケースまで見せているのは、その思想の裏返しだろう。

一方で、これは「万能全文検索が完成した」という話ではない。ベンチマークはかなり丁寧だが、あくまで特定のコーパスとクエリの組み合わせだ。全文検索の現場では、短い単語のノイズ、形態素処理、多言語、同義語、検索結果の説明性、運用時の再インデックス戦略など、数字に出にくい厄介ごとがたくさんある。TINが速いことは見えたが、速さだけで採用が決まるわけではない。とはいえ、Postgres内でここまでやれれば、アプリ側の構成はかなりシンプルになる。そこに価値を感じるチームは多いはずだ。

ベンチマークの見せ方はかなり攻めているが、読み方には注意が要る

この記事は比較の仕方が明確で、読みやすい反面、見る側に少し注意も必要だと思う。たとえば「TINが何倍速い」という主張は印象的だが、全ての競合が全項目を完走しているわけではない。GINはメモリ不足で落ちる場面があり、pg_textsearchはtop-kやCOUNT(*)に対応できない場面がある。つまり、比較の土俵が完全にそろっているわけではなく、実運用の選定では「どれが一番速いか」より「自分の使いたいクエリを誰が支えられるか」を先に見たほうがいい。

それでも、この記事が示したいことは伝わる。全文検索は、読み取り専用のデモなら見栄えがするが、実際には書き込みが混ざった瞬間に崩れやすい。PlanetScaleはそこを正面から測っている。特に10分間での更新件数の差は、検索システムをDBの横に置くか、中に抱え込むかを考える人には刺さる数字だと思う。更新を受け止めながら読める、というのは検索基盤ではかなり重い要求だからだ。

それでも本当に効いてくるのは、検索を“運用コスト”ごと下げられるかどうか

個人的には、TINの価値は検索速度そのものより、検索を別コンポーネントに逃がさなくて済むところにあると思う。検索専用エンジンを足すと、同期、再構築、障害時の整合性確認、権限管理、監視、バックアップの考え方まで増える。アプリ側から見れば、単に検索APIが増えるだけではない。Postgresの中に収まるなら、その面倒がかなり減る。これは特に中規模チームに効く。専任の検索基盤担当がいない会社ほど、運用の軽さはそのまま価値になるはずだ。

ただし、ここで気をつけたいのは「速いから全部TINでいい」とはならないことだ。専用検索エンジンには、検索品質の細かな調整や分散前提のスケーリングで強いものがある。TINはPostgresに最適化された選択肢として魅力的だが、検索体験をどこまで作り込みたいかで向き不向きは分かれるだろう。この記事はその点をあえて広げすぎず、「Postgresで実用的に動く全文検索はこれだ」と一点突破している。そこは自信の表れでもあり、プロダクト戦略としても分かりやすい。

PlanetScaleが狙っているのは、検索の理想形より“採用しやすさ”だと思う

記事を読んでいると、TINは研究成果の発表というより、導入のハードルを下げるための製品設計に見える。CREATE INDEX ... USING tin(...) という見た目の素直さもそうだし、更新と検索を同じDBで扱えることを強く押しているのもそうだ。検索は欲しいが、別システムを増やすほどの余力はない。そういうチームにとって、これはかなり現実的な提案になる。

同時に、PlanetScaleがここで競合に対してかなりはっきりした優位を示したのは、Postgres周辺の全文検索市場がまだ固まり切っていないからだろうとも思う。標準のGINでは足りず、既存拡張も要件を全部満たせない。その隙間に、実運用向けの全文検索を差し込む余地がある。TINがその穴をどこまで埋められるかは、これからの利用例次第だが、少なくともこの記事は「Postgresで検索をやるなら、もう少し本気で考えていい」と強く印象づける内容だった。


参考: Introducing TIN: full-text search for Postgres — PlanetScale

同じ著者の記事