堀本です。 原因がわかりましたので、ご報告いたします。 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 > > > ----- > 増田