[groonga-dev,01944] Re: FULLTEXTインデックス以外での絞り込みについて

アーカイブの一覧に戻る

sinoh****@netag***** sinoh****@netag*****
2013年 12月 6日 (金) 11:13:11 JST


篠原と申します。

本件と直接関係ないのですが、

全文検索は、爆速なのですが、通常のインデックス性能が、それに比べ遅いので
1. ちょっとテストしたら速かった。
2. アプリ作成してたら、なんか遅い。思ったのと違うー
3. テーブル設計から見直し。
な経験をされる方ってけっこういらっしゃるのではないでしょうか?

- そもそも普通のインデックスの速度ってこれが限界?
- この例のテーブルでは、PARTITION使えば速くなると思いますが、
 mroonga は、PARTITION 使えないよ。
- SPIDERで分散すればいいけどPARTITON,SUBPARTITION使って
 長いテーブル定義になって、見通しわるすぎる。
 
最近の悩みを書いてみました。


Kouhei Sutou <kou****@clear*****>さん:
> 須藤です。
> 
> In <CAKRtL1u=fGRGxvysCjf1w1DSKaa_VxmzdZBy_A9p+0****@mail*****>
>   "[groonga-dev,01940] FULLTEXTインデックス以外での絞り込みについて" on Wed, 4 Dec 2013 18:32:56 +0900,
>   Horikoshi Yuki <horik****@gmail*****> wrote:
> 
> > FULLTEXTインデックスでの全文検索自体は非常に高速に動いているのですが、
> > 掲題の通りFULLTEXTインデックス以外での絞り込みを利用した際、
> > 全文検索でのヒット件数が多い場合(数千件〜)に速度が遅くなってしまいます。
> 
> うーん、手元のふつうのPC(メモリー8GB)では再現しませんでし
> た。(xxxというテーブル名にしました。)
> 
> mysql> SHOW CREATE TABLE xxx\G
> *************************** 1. row ***************************
>        Table: xxx
> Create Table: CREATE TABLE `xxx` (
>   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
>   `name` text,
>   `birth_year` smallint(5) unsigned DEFAULT NULL,
>   PRIMARY KEY (`id`),
>   KEY `birth_year` (`birth_year`),
>   FULLTEXT KEY `name` (`name`)
> ) ENGINE=mroonga AUTO_INCREMENT=10000001 DEFAULT CHARSET=utf8
> 1 row in set (0.00 sec)
> 
> mysql> SELECT COUNT(*) FROM xxx;
> +----------+
> | COUNT(*) |
> +----------+
> | 10000000 |
> +----------+
> 1 row in set (0.00 sec)
> 
> mysql> SELECT COUNT(*) FROM xxx WHERE MATCH(name) AGAINST ("山田");
> +----------+
> | COUNT(*) |
> +----------+
> |  1000000 |
> +----------+
> 1 row in set (0.31 sec)
> 
> mysql> SELECT COUNT(*) FROM xxx WHERE birth_year > 1973;
> +----------+
> | COUNT(*) |
> +----------+
> |  4996106 |
> +----------+
> 1 row in set (1.24 sec)
> 
> mysql> SELECT COUNT(*) FROM xxx WHERE MATCH(name) AGAINST ("山田") AND birth_year > 1973;
> +----------+
> | COUNT(*) |
> +----------+
> |   500510 |
> +----------+
> 1 row in set (1.17 sec)
> 
> mysql> SELECT COUNT(*) FROM xxx WHERE MATCH(name) AGAINST ("山田") AND birth_year > 1973 ORDER BY birth_year LIMIT 0,50;
> +----------+
> | COUNT(*) |
> +----------+
> |   500510 |
> +----------+
> 1 row in set (1.18 sec)
> 
> 
> ↑ではCOUNT(*)でやっていますが、*でやっても同じくらいの速度
> でした。
> 
> で、それはそれとして。。。
> 
> > おそらく、この事象については以下のチケット
> > http://redmine.groonga.org/issues/447
> > に記載された内容だと思うのですが、現状mroongaで回避策などはありますか?
> > (チケット発行日が3年前でしたので、既に解決済みであれば申し訳ありません)
> 
> ここに書かれていることを実現する仕組みがすでにMroongaには入っ
> ているのです!
> 
> ただ、それぞれの演算子に対して実施する必要があって、今はすべ
> ての処理に対応しているわけではありません。今は、
> 
>   MATCH AGAINST AND INT系のカラム = 数値 ORDER BY LIMIT;
> 
>> 
>   MATCH AGAINST AND 文字列系のカラム = 文字列 ORDER BY LIMIT;
> 
> のときのみ効きます。
> 
> http://mroonga.org/ja/docs/userguide/storage.html#optimisation-for-order-by-limit-in-full-text-search
> 
> をより進めた機能なのですが、ドキュメントが追いついていません
> ね。。。
> 
> ただし!今回のように
> 
>   INT系のカラム < 数値
> 
> には対応していなかったのでリポジトリーの方では対応しておきま
> した。
> 
> もし、
> 
>   SELECT * FROM 名簿 WHERE MATCH(NAME) AGAINST ("山田") AND birth_year = 1973;
> 
> では遅いままで、ORDER BY LIMITを付けて
> 
>   SELECT * FROM 名簿 WHERE MATCH(NAME) AGAINST ("山田") AND birth_year = 1973 ORDER BY birth_year LIMIT 0,50;
> 
> とすると速くなるのであれば、次のリリースを使えば高速になると
> 思います!
> 
> > 大変お恥ずかしい話なのですが、未だこの問題の解決方法が見つけられず
> > senna + tritonnからの移行が出来ておりません・・・・
> 
> 次のリリースで移行できるはずです!
> 
> -- 
> 須藤 功平 <kou****@clear*****>
> 株式会社クリアコード <http://www.clear-code.com/> (03-6231-7270)
> 
> Groongaサポート:
>   http://groonga.org/ja/support/
> パッチ採用はじめました:
>   http://www.clear-code.com/recruitment/
> コミットへのコメントサービスはじめました:
>   http://www.clear-code.com/services/commit-comment.html
> 
> _______________________________________________
> groonga-dev mailing list
> groon****@lists*****
> http://lists.sourceforge.jp/mailman/listinfo/groonga-dev


_______________________
篠原 明彦 (Akihiko Shinohara)/ NetAgent
     http://www.NetAgent.CO.JP/
     TEL: 03-5625-1243
     FAX: 03-5625-9008




groonga-dev メーリングリストの案内
アーカイブの一覧に戻る