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