LIKEとpg_bigmとPGroongaPostgreSQLアンカンファレンス@東京(2015/5/30)でPostgreSQLの日本語全文検索まわりについて紹介しようかとたくらんでいます。現時点(2015-05-25)でキャンセル待ちで、当日参加できないかもしれないので紹介しようと用意している内容をここにまとめます。LIKEとpg_bigmとPGroonga内容この資料の目的は、PostgreSQLで使える次の3つの方法の特性を紹介し、ユーザーが適切な方法を選択するための材料を提供することです。LIKEpg_bigmPGroonga(ぴーじーるんが)LIKELIKEのメリット・デメリットは次の通りです。「データが少ないかどうか」)です。どのくらいなら「十分速い」のでしょうか。「十分速い」かどうかは「検索対象のデータでの計測結果」と「要件」で判断できます。どちらもケースバイケースですが、参考情報としての計測結果なら示すことができます。参考情報としてpg_bigmでいろんなデータを日本語検索してみよう!のLIKEの結果を使ってみましょう。この記事では次の3つのデータを検索しています。青空文庫の書籍一覧データ住所データ日本版Wikipediaのタイトル一覧データそれぞれみていきましょう。「青空文庫の書籍一覧データ」です。このデータの特性と検索速度は次の通りです。6.673ms6msで結果が返ってくるのであれば多くの要件で「十分速い」と言えるでしょう。このデータでは日本語全文検索の方法としてLIKEはアリということです。次のデータは「住所データ」です。このデータの特性と検索速度は次の通りです。70.684ms70msで結果が返ってくるのであれば多くの要件で「十分速い」と言えるでしょう。このデータでも日本語全文検索の方法としてLIKEはアリということです。最後のデータは「日本版Wikipediaのタイトル一覧データ」です。このデータの特性と検索速度は次の通りです。943.450ms1秒くらいで結果が返ってくるのでは、「十分速い」というのは要件次第でしょう。この規模のデータでは日本語全文検索の方法としてLIKEは使えるかもしれないし使えないかもしれない、といったところです。これまでの結果をまとめると次の通りです。LIKEで十分かどうかを判断する場合は、実際のデータの傾向と検索時間を材料として検討します。943.450msでは、LIKEでは十分速くない場合はどうしたらよいでしょうか。次のどちらかの方法を選びます。pg_bigmPGroongapg_bigmpg_bigmのメリット・デメリットは次の通りです。データ更新が遅くなる)ヒット数に比例して遅くなるpg_bigmはデータ量が多くても高速ですが、ヒット数が多いほど遅くなる特性があります。pg_bigmが十分速いかどうかを判断するためにも、LIKEと同様に「検索対象のデータでの計測結果」と「要件」が必要です。LIKEとは注目するポイントが異なります。それでは、検索結果例を見ながら注目するポイントを確認しましょう。groonga/wikipedia-searchにあります。手順もまとまっているので誰でも追試することができます。ここで使うデータは日本語版Wikipediaの本文です。このデータの特性は次の通りです。3777バイト注目するポイントの1つ目はインデックス作成時間です。元データのロード時間とインデックス作成時間は次の通りです。約16分でロードできるデータのインデックス作成に約6時間かかるのは十分速いでしょうか。それとも遅いでしょうか。要件と照らしあわせて検討します。この時間はインデックス全体を1から作成する時間です。常に少量ずつ更新するという要件であればこの時間はあまり関係ありません。そのような要件の場合は、少量のデータの更新が滞らない(更新処理が溜まっていかない)くらいの速度がでていれば十分速いと判断できます。注目するポイントの2つ目はヒット数と検索時間の関係です。0.556spg_bigmはヒット数が多くなるほど遅くなります。数百件ヒットのときは0.1秒ですが、1万7千件のときは1秒ちょい、2万2千件のときは約2.5秒となりました。このデータではヒット数が増えるほど遅くなる傾向がよりわかりやすいデータになっています。いうのは、このデータは1レコードあたりのデータが大きいからです。pg_bigmは1レコードあたりのデータが大きいと遅くなりやすい特性があります。検索語が2文字以下の場合はヒット数が多くても遅くなりにくいという特性があります。例では62万件ヒットしても0.5秒で結果を返しています。このような特性があるpg_bigmなので、データによっては遅いと判断する場面も十分速いと判断する場面もあるでしょう。PGroongaLIKEでは遅い場合、pg_bigm以外の選択肢はPGroongaです。PGroongaのメリット・デメリットは次の通りです。使用ディスクサイズが多いPGroongaはデータ量が多くてもヒット数が多くても速度が落ちにくく、インデックス作成も高速ですが、PostgreSQLとの連携度合いはpg_bigmほどではありません。pg_bigmはPostgreSQL標準のストリーミングレプリケーション機能を使えますが、PGroongaは使えません。これはPostgreSQL側が連携する機能を提供していないことが原因です。今後連携できる機能が提供される見込みですが、現時点で連携できないことは事実です。PGroongaを選ぶかどうかの基準は他の方法では遅いケースがPGroongaだと速いかどうかです。そのためには同じデータでpg_bigmと比較する必要があります。それでは、pg_bigmと同じデータを使った場合のPGroongaの速度を確認しましょう。インデックス作成時間です。参照しやすいようにpg_bigmのインデックス作成時間も再掲しています。PGroongaは元データのロード時間の2倍いかないくらいの時間でインデックスを作成しています。pg_bigmと比べると1/14の時間でインデックスを構築できています。インデックスのために使用するディスクサイズは大きいです。元データロード直後のデータベースサイズ4.0GiBPGroongaの使用ディスクサイズ14.0GiBpg_bigmの使用ディスクサイズ3.6GiBディスクサイズが小さい環境で動かす場合は問題になるかもしれません。次は検索時間を確認しましょう。0.556sPGroongaはpg_bigmほどヒット数の多さに影響をうけていません。62万件ヒットする場合でも0.6秒ちょいで結果を返しています。PGroongaは全体的に高速ですが、検索語が2文字以下の場合はpg_bigmの方が高速です。PostgreSQLとの連携度合いよりも性能が大事な要件な場合で、pg_bigmでは性能が落ちやすい規模のデータではPGroongaが選択肢になるでしょう。まとめPostgreSQLで日本語全文検索の方法として次の3つの方法を紹介しました。LIKEpg_bigmPGroongaデータが少ないならLIKEで十分です。要件次第ですが、1レコード数十バイトの小さなデータなら百万件くらいまでいけるかもしれません。データが多いならpg_bigmかPGroongaを選びます。次のような場合はpg_bigmがよいでしょう。2文字以下での検索がほとんど1レコードあたりのデータが小さいヒット数が多くなることがほとんどないストリーミングレプリケーションを使いたいpg_bigmで次のような問題があるならPGroongaがよいでしょう。1レコードあたりのデータが大きいヒット数が多くなるケースを考慮しないといけない更新が多くてインデックス更新速度がネックになるちなみに、PGroongaでもレプリケーションをする方法はあります。PostgreSQLクラスターの作り方を参考にしてください。最後に、PostgreSQLの日本語全文検索に興味のある方にお願いです。この説明の中のpg_bigmとPGroongaの性能確認で参照したベンチマークをあなたの環境でも動かして結果を教えてもらえないでしょうか?同じ傾向があるか確認したいのです。ベンチマークの実行方法や必要な環境などの詳細は協力者募集:PGroongaとpg_bigmのベンチマークを実行を参照してください。4.0とGFDLのデュアルライセンスで自由に利用できます。クリアコードはプログラミングが楽しいソフトウェア開発者を1名募集しています。クリアコードは「クリアコードをいい感じにする人」を1名募集しています。クリアコードはフリーソフトウェア開発で培った技術力を提供しています。Thunderbird)とRubyとGroonga(全文検索)に関連した開発を得意としています。