Kouhei Sutou
kou****@clear*****
2013年 8月 20日 (火) 15:20:23 JST
須藤です。 In <CANM+HhcZRHbzyG+-aay1ntv=Np-eKWfc=xzqtqKGEnT5E_=D7g****@mail*****> "[groonga-dev,01649] Re: mroongaストレージモードの複数インデックスを使用した検索について" on Mon, 19 Aug 2013 23:22:57 +0900, Naoya Murakami <visio****@gmail*****> wrote: > 1.ベクターカラムについて > > ベクターカラムを少しだけ触ってみました。 > 参照先のテーブルの語彙は各レコードで共有される、参照元でDELETE、UPDATEしても、 > 参照先のテーブルの語彙は消えない、等、若干くせのある挙動をしますが、 > mroongaでベクターカラムのドリルダウンができるようになってすばらしいです! あぁ、参照先のテーブルはインデックスみたいなものだと考えてく ださい。参照元のデータの更新だけ考えて、参照先のことは考慮し なくてよいです。 > 少し使っただけですが、以下の点が気になりました。 > > ・キーのリファレンス指定(?)を間違えると、mysqldがクラッシュします。 > 例: > 参照先テーブル名:reference > 参照元テーブルでのキー指定:KEY `ref` (`ref`) COMMENT 'table "referenc"' そんなこともあるだろうなぁと思います。。。 見ておきます。。。 > ・以下のようにインデックスにテーブルを指定すると、参照元のテーブルに > 参照先のレコードをもとにしたキーが生成されるのでしょうか? > キーサイズが大きくなり、キーサイズ合計の4G制限がさらにこわくなってくるなぁと感じました。 > KEY `ref` (`ref`) COMMENT 'table "reference"' いえ、違います。これは、参照先のテーブル(reference)に参照元 のカラム(ref)の値をもとにしたキーが生成されます。refの1つ1 つの値が大きくて種類も多いと4GBの制限に到達するかもしれませ ん。と書いて伝わるかどうかがわかりませんが。。。 例えば、 https://github.com/mroonga/mroonga/blob/master/test/sql/suite/mroonga/storage/fulltext/groonga/t/varchar_vector.test にある CREATE TABLE Tags ( name VARCHAR(64) PRIMARY KEY ) DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='default_tokenizer "TokenDelimit"'; CREATE TABLE Bugs ( id INT UNSIGNED PRIMARY KEY, tags VARCHAR(40) COMMENT 'type "Tags", flags "COLUMN_VECTOR"', FULLTEXT INDEX bugs_tags_index (tags) COMMENT 'table "Tags"' ) DEFAULT CHARSET=utf8; だと、 FULLTEXT INDEX bugs_tags_index (tags) COMMENT 'table "Tags"' で column_create Tags bugs_tags_index COLUMN_INDEX|WITH_POSITION Bugs tags というgroongaのインデックスができます。 > ・参照元テーブルのカラムのレコード長は、あらかじめ長めにとっておく必要があり、 > また、キーの4Kbyte制限もかかってくるので、長い文字列やあまりの多数の > レコードの格納には不向きだなと感じました。 はい、その通りです。 > ・TokenDelimitだけだと、英文等空白を含む文字列を扱えないため、ベクターカラムを使うに > あたっては、セミコロン等、多少区切り文字のバリエーションがあると嬉しいと感じました。 トークナイザーにパラメーターを渡せるようにしたいなぁという話 はでるのですが、まだ実現できてません。。。 > TokenDelimitを1文字変えるだけで実装できたので、当方はTokenDelimitSemiColon > というトークナイザを作ってベクターカラムを構成しました。 おぉ。TokenDlimitNullという'\0'区切りのやつが組み込みであるの ですが、それでもよいかもしれませんね。 > しかし、こうすると、selectは空白区切りで出力され、insert,updateはセミコロンという > ちぐはぐになりました。。でも、便利なので、セミコロンで使おうと思ってます。 たぶん、ここの' 'を';'にするとセミコロン区切りになります。 https://github.com/mroonga/mroonga/blob/master/ha_mroonga.cpp#L9808 が、汎用的ではないんですよねぇ。 > ・ベクターカラムのドリルダウン便利だなぁと思ったのですが、複数のテーブルを > 横断してのドリルダウンは難しいですよね? > できるのは、ドリルダウンソートしてアプリケーション側で足しこむぐらいかなぁと思っています。 イメージがわかないのですが、たぶん、できないと思います。アプ リケーション側での対応になると思います。 > 2.order by limit の高速化について > >>別の方法として、AGAINST("..." IN BOOLEAN MODE)の中でgroonga >>の検索条件を指定するという方法があります。 > > この方法を試したのですが、うまくAND条件で絞り込むことができませんでした。 むむ。 > varchar equalのorder by limitのoptimizationを追加していただいたことにより、 > where match ... against and varchar = "hogehoge"の形では、 > order by の最適化が動くようになりました!ありがとうございました! おぉ、もう気づいているとは。。。! > (4)AGAINST("..." IN BOOLEAN MODE)の中で全文検索+前方一致検索条件を指定 > select app_id from ftext_199x where > match(title,abstract,claims,description) against ("device > varchar:hogehoge*" in boolean mode) order by int limit 1,10; > 0.889sec > 後ろの条件で絞り込めない すみません。。。 「カラム名:値」という書式は無効化してありました。。。 https://github.com/mroonga/mroonga/blob/master/ha_mroonga.cpp#L7686 の GRN_EXPR_SYNTAX_QUERY | GRN_EXPR_ALLOW_LEADING_NOT; に | GRN_EXPR_ALLOW_COLUMN を足して GRN_EXPR_SYNTAX_QUERY | GRN_EXPR_ALLOW_LEADING_NOT | GRN_EXPR_ALLOW_COLUMN; とすれば「カラム名:値」が使えるようになります。 あと、BOOLEAN MODEはデフォルトでORなので↓のように最初に「+」 をつけないといけません。 "device +varchar:hogehoge*" in boolean mode ↑のフラグはカスタマイズできるようにしたいなぁと思ったっきり 手付かずだったのでした。。。どんな風にカスタマイズできれば MySQLになじむかしら。。。 -- 須藤 功平 <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