[groonga-dev,01642] Re: mroongaストレージモードの複数インデックスを使用した検索について

Back to archive index

Kouhei Sutou kou****@clear*****
2013年 8月 16日 (金) 12:05:41 JST


須藤です。

In <CANM+HheURK=x7Xk=h1K7njFBLRt4tR4GndAwPs=i-_cn=-AHpg****@mail*****>
  "[groonga-dev,01639] mroongaストレージモードの複数インデックスを使用した検索について" on Thu, 15 Aug 2013 20:27:38 +0900,
  Naoya Murakami <visio****@gmail*****> wrote:

> mroongaラッパーモード(MYISAM)とmroongaストレージモードで
> まったく同じテーブル内容で性能等を比較してみたところ、サイズはほぼ同じでストレージモードのほうが早いという結果がでました。

おぉ!

> Q1.MySQLでは、1つのクエリで1つのインデックス(複合インデックス含む)しか使用できないという仕様があるが、groongaでは複数のインデックスを同時に使えるかどうか?

groongaでは使えます。

> 使える場合、mroongaで作成されたgroongaテーブルにmroonga_commandで複数のインデックスが使われるようにselectすると、普通にSQLでselectするより早く検索することができるかどうか?

速く検索できる気がします。ただ、groongaからの結果はJSONで返っ
てくるので、検索以外のところで多少オーバーヘッドがあるとは思
います。

もし、単純な条件であれば、SQLでも速くできます。

例えば、ORDER BY LIMITをつけることで速くできます。

  http://mroonga.org/ja/docs/userguide/storage.html#optimisation-for-order-by-limit-in-full-text-search

このとき、MATCH AGAINSTの他にWHEREの条件を指定した場合でも高
速に検索できるケースがあります。が、あれ、ドキュメントに書い
ていないですね。。。

今のところINT型の等価比較も一緒に書いても↑の最適化が効くよ
うになっています。例えば、以下のように書いても高速に動きます。

https://github.com/mroonga/mroonga/blob/master/test/sql/suite/mroonga/storage/optimization/order_limit/t/equal_int.test#L47

  SELECT * FROM diaries
           WHERE MATCH(content) AGAINST("今日" IN BOOLEAN MODE) AND
                 month = 11
           ORDER BY day LIMIT 1,2;

他の型や演算のサポートも難しくないので「やればできる」類のも
のなのですが、そこはまだ手が回っていなくて今のところはINT型
の等価比較だけです。

なので、もし、「この型の演算を速くしたい」という要望があれば、
それを優先的に対応するというのが現実的かなぁと思っています。


別の方法として、AGAINST("..." IN BOOLEAN MODE)の中でgroonga
の検索条件を指定するという方法があります。

前述のSELECTを↓のようにしても速く動くはずです。

  SELECT * FROM diaries
           WHERE MATCH(content) AGAINST("今日 month:11" IN BOOLEAN MODE)
           ORDER BY day LIMIT 1,2;

AGAINSTの中のクエリーで「month:11」と書くと「monthが11である
こと」という条件になります。

「カラム名:値」で等価条件、

  http://groonga.org/ja/docs/reference/grn_expr/query_syntax.html#equal-condition

「カラム名:<値」で少なり条件、

  http://groonga.org/ja/docs/reference/grn_expr/query_syntax.html#less-than-condition

など、いくつか演算方法が用意されています。

「カラム名」の部分はMATCH(...)で指定されていないものでも大丈
夫です。

> Q2.現状、mroongaでは、groongaのベクターカラムは使えないという認識でよいか?
> データ構造の違いから、実現が難しそうな気がしますが、ベクターカラムはすごい便利そうだなぁと思っています。

実は、実験的な機能という扱いですが、使えるようになっています。

https://github.com/mroonga/mroonga/blob/master/test/sql/suite/mroonga/storage/column/groonga/vector/t/reference.test#L32

  CREATE TABLE Bugs (
    id INT UNSIGNED PRIMARY KEY,
    tags TEXT COMMENT 'flags "COLUMN_VECTOR", type "Tags"'
  ) DEFAULT CHARSET=utf8;

というように、COMMENTとして「flags "COLUMN_VECTOR"」を指定す
るとベクターカラムになります。

SQLとなじませるのが難しいのでコツがいります。。。たぶん、タ
グ検索の用途が一番なじませやすいのではないかと思います。
ポイントは、↑のテストのように参照型のベクターカラムにして参
照先のテーブルに「default_tokenizer "TokenDelimit"」を指定し、
カラムの値はスペース区切りの文字列として
「"Linux MySQL groonga"」というように指定するところです。

検索するときは

  MATCH(tags) AGAINST("groonga" IN BOOLEAN MODE)

でいけると思います。

> ちなみに、余談ですが、いままでは、以下の点を考慮してラッパーモードを選んでいました。バグフィックスがなされ、また、vm.max_map_countのパラメータチューニング等、だいぶこなれてきて強制終了するケースが減ったので、ストレージモードでもいけるだろうと判断しました。
> 
> (1)ラッパーモードだと強制終了がかかったときでも実データを復旧しやすい。被害が全文インデックスまでに抑えられる。
> (2)MYDがファイル1つなので、全文インデックスはSSDのような
> 高速ストレージに配置し、実データのMYDのみを別ストレージに移して、
> シンボリックリンクを張りやすい。ストレージモードの場合、ファイル数が多く、また、インデックスと実データが区別つきづらい。
> (3)MYDがファイル1つなので、実データだけをバックアップすることが容易。
> (4)MYDを読み取り専用に圧縮することにより、実データサイズを3、4割に抑えることができる。
> (5)カラムストアなので、ストレージモードは、MyISAMよりも実データがでかい(これは、勘違いでした)。

あぁ、なるほど。こういう観点があるんですね。
共有してもらってありがとうございます!参考になります!

-- 
須藤 功平 <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 メーリングリストの案内
Back to archive index