須藤です。 増田さんに再現している実データを提供してもらって確認できまし た。 詳細は後述しますが、今回のケースだと mroonga_match_escalation_thresholdを-1にして「検索のエスカレー ション」を無効にするのがいいんじゃないかと思います。 https://mroonga.org/ja/docs/reference/server_variables.html#mroonga-match-escalation-threshold ↑は動的に変更する例だけが載っていますが、my.cnfに↓と [mysqld] loose_mroonga_match_escalation_threshold=-1 書いて永続的にするのがよいと思います。一時的に試す場合は SET mroonga_match_escalation_threshold = -1; とGLOBALなしで試してください。これでそのセッションだけこの変 数の値が変わります。SET GLOBALだとログインし直さないと変更が 反映されません。 以下、詳細です。 Groongaは検索精度を維持しつつも多少精度を落としてもなにかし ら検索できるような作りになっています。そのための機能の1つが 「検索のエスカレーション」です。 https://groonga.org/docs/spec/search.html ざっくりと説明すると、まずは精度重視で検索し、あらかじめ決め ておいた件数以上のレコードが見つからない場合は精度を落として ゆるく検索するという機能です。こうすることで適切ではないクエ リーの場合でもユーザーは検索結果から何かしらヒントを得てより 適切なクエリーで再チャレンジしやすくなります。 (Googleももしかして?とか言いながら実際のクエリーとは違うク エリーでの検索結果を返すことがありますがそういうような感じで す。) 今回のケースでは最後のトークンだけ前方一致検索をしてゆるく検 索しています。ちなみに、今回のケース (https://kirorosuu.com/kiro-f2-04q)の最後のトークンはqです。 qで前方一致をしてゆるく検索するということはqから始まるどのトー クンもヒットするということです。 https://kirorosuu.com/kiro-f2-04q だけでなく https://kirorosuu.com/kiro-f2-04qa や https://kirorosuu.com/kiro-f2-04qxxxxxxxxxxx でもヒットする ということです。 今回の場合、qから始まる既存のトークンが非常にたくさん(約700 万件)あってそれらを集めるところで時間がかかっていました。内 訳は、手元では前方一致検索に1秒弱、前方一致検索で集めたqから 始まる既存トークンすべての情報をインデックス内から取得すると ころで4秒弱かかっていました。とりあえず、前者の1秒弱のところ は一時データを作らないようにして高速化したのですが、後者のと ころはすぐに高速化できる余地がなさそうなのでそのままです。 (上限を設けて枝刈りするとかで高速化できますけど、そうすると 従来はヒットしていたレコードがヒットしなくなったりするのでも う少し賢く頑張らないといけなそう。) さて、今回のケースはURLの検索ですが、URLの検索ではGroongaの このゆるい検索はあまり有効ではないはずです。もし、必要ならこ のゆるい検索ではない方法で実現したほうがよいです。たとえば、 前方一致検索ができるインデックスを作って https://kirorosuu.com/kiro-f2-04qで前方一致検索することでも 実現できます。(もちろんMroongaではできますし、InnoDBでもイ ンデックス+LIKE+'https://kirorosuu.com/kiro-f2-04q%'でできる はず。) ということで、今回のケースは「検索のエスカレーション」でのゆ るい検索を高速化するよりそもそもこの機能を使わないほうがよい と思います。 In <20220****@clear*****> "[groonga-dev,04997] Re: mroonga 記号を含む検索クエリのレスポンス長時間化" on Thu, 02 Jun 2022 15:55:47 +0900 (JST), Sutou Kouhei <kou****@clear*****> wrote: > 須藤です。 > > すみません、これ、再現できていたつもりだったんですが再現でき > ていないような気がしてきました。増田さんが使った1000万行のデー > タを提供してもらうことはできますか? > > 公開できないデータの場合、kou****@clear*****にデータのダウン > ロードURLを送ってもらうのでも大丈夫です。 > > In <CAA6M8XGNn_KuAveekv7Egmbt3CXM4jEc1rmxwbOrJAHs4D=S6w****@mail*****> > "[groonga-dev,04996] Re: mroonga 記号を含む検索クエリのレスポンス長時間化" on Wed, 25 May 2022 16:34:54 +0900, > 増田紘也 <koya.****@roote*****> wrote: > >> 堀本様 >> >>>この結果セットを入れる領域のサイズは、検索対象のテーブルのレコード数(最大でその分必要なため)なのですが、 >>>ヒット数が0のときは無駄に結果セットの容量を確保して遅くなってしまいます。 >> >> そういうことだったんですね!理解できました。 >> >>>Mroonga(のバックエンドで動いているGroonga)に改良を入れることで、この現象を改善できるようにします。 >>>Groongaに改良を入れたら、再度ご連絡しますので、改良を入れたGroongaを使って現象が解消するかをご確認いただければ >>>と思います。 >> >> ご対応いただきありがとうございます! >> 最新バージョンを追ってみようと思います。 >> >> >> 今回は迅速なご対応ありがとうございました。 >> >> 増田 >> >> 2022年5月25日(水) 16:12 Horimoto Yasuhiro <horim****@clear*****>: >> >>> 堀本です。 >>> >>> 原因がわかりましたので、ご報告いたします。 >>> Mroonga(のバックエンドで動いているGroonga)は検索結果を入れる領域を予め確保しておくことで >>> 検索結果を作る速度を向上させて、検索パフォーマンスを改善しています。 >>> >>> この結果セットを入れる領域のサイズは、検索対象のテーブルのレコード数(最大でその分必要なため)なのですが、 >>> ヒット数が0のときは無駄に結果セットの容量を確保して遅くなってしまいます。 >>> >>> たとえば、検索対象のテーブルが1000万行あったら検索結果を入れる領域も1000万行(追加確保必要なしで)入れられるように >>> 準備することになりそれが遅くなっている原因です。 >>> >>> Mroonga(のバックエンドで動いているGroonga)に改良を入れることで、この現象を改善できるようにします。 >>> Groongaに改良を入れたら、再度ご連絡しますので、改良を入れたGroongaを使って現象が解消するかをご確認いただければ >>> と思います。 >>> >>> 以上です。失礼いたします。 >>> >>> From: 増田紘也 <koya.****@roote*****> >>> Subject: [groonga-dev,04992] mroonga 記号を含む検索クエリのレスポンス長時間化 >>> Date: Fri, 20 May 2022 15:55:33 +0900 >>> >>> > お世話になっております。増田と申します。 >>> > 表題の件について伺います。 >>> > >>> > >>> > ## 記号を含む検索クエリのレスポンス長時間化 >>> > >>> > MariaDB + >>> > >>> Mroongaのストレージモードで利用しています。特定のテーブル、検索クエリで全文検索したときにレスポンスに10秒以上かかる現象が発生しました。テーブルのレコード数はおよそ1,000万行です。この事象が並列で飛ぶとメモリ利用率が高まり、DBがダウンしてしまいます。 >>> > 内部でも調査しましたが、原因究明に至らなかった為こちらで報告します。 >>> > >>> > ### 環境 >>> > MariaDB 10.4.17 >>> > Mroonga 10.01 >>> > >>> > ### テーブル定義(詳細は伏せてあります) >>> > >>> > ```SQL >>> > CREATE TABLE `urls` ( >>> > `id` int(11) NOT NULL AUTO_INCREMENT, >>> > `url` mediumtext DEFAULT NULL, >>> > PRIMARY KEY (`id`), >>> > FULLTEXT KEY `fulltext_url` (`url`) >>> > ) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4; >>> > ``` >>> > >>> > ### 再現SQL >>> > >>> > ```SQL >>> > SELECT `urls`.* >>> > FROM `urls` >>> > WHERE MATCH(urls.url) AGAINST('+https://kirorosuu.com/kiro-f2-04q' IN >>> > BOOLEAN MODE); >>> > ``` >>> > >>> > ```SQL >>> > SELECT mroonga_command('select urls --match_columns url --query >>> > +https\\\\://kirorosuu.com/kiro-f2-04q --output_columns _id'); >>> > ``` >>> > >>> > ### 検証したこと >>> > >>> > - Mroongaバージョンのアップグレード >>> > Mroonga 12.02 >>> > MariaDB 10.4.24 >>> > にて同テーブルを用意して再現することを確認しました。 >>> > >>> > - テーブルサイズ(レコード数)の変更 >>> > レコード数を10万に減らしたテーブルを用意し、再現テストを行いました。 >>> > その結果、10万レコードに減らしたテーブルでは再現しませんでした。 >>> > >>> > >>> > 正常系(レスポンスが1秒未満)、異常系(レスポンスが10秒以上)でのgroonga.logを比較したところ、異常系では`rehash >>> > temporary`の箇所で時間がかかっていることまで判明しております。 >>> > >>> > ## 添付ファイル >>> > >>> > - `正常系_groonga.log`はレコード数を10万行に絞ったテーブルで全文検索したときのgroonga.log >>> > - `異常系_groonga.log`はレコード数が1,000万行のオリジナルテーブルで全文検索したときのgroonga.log >>> > >>> > >>> > ----- >>> > 増田 >>> > _______________________________________________ > groonga-dev mailing list > groon****@lists***** > https://lists.osdn.me/mailman/listinfo/groonga-dev