Kazuho Oku
kazuh****@gmail*****
2008年 2月 5日 (火) 15:17:35 JST
奥です。 本件について、以下の修正を加えたパッチを作成しました。バグ修正の度にいちいちこちらに投稿するのもどうかと思ったのと、ある程度まとまった形になったかな、ということで、自分のブログのほうで書かせていただきました。ついでに 2ind patch との比較もやってみました。 http://labs.cybozu.co.jp/blog/kazuho/archives/2008/02/triton-embed-primary-key.php 以下、v2 からの修正点です。 1) 全文索引のプライマリキーへの追加可否を設定可能に set global senna_embedded_pkey=ON している状況下で create index した場合のみ、全文索引にプライマリキーを格納するようにしました。このグローバル変数が OFF の場合は、従来と同じ形式のインデックスが生成されます。 2) バグ修正 2ind パッチを使って別インデックスを force index している場合に検索できない問題を修正しました。 3) スコア値をヒット数ではなく、ヒット数/テキスト長とするパッチを同梱 -DENABLE_SENNA_PSEUDO_TF を使用して make し、かつ、set global senna_pseudo_tf=ON している状況下で create table した場合に有効になります。 これでほぼ形になったかと思います。3 はいずれちゃんとした TF-IDF 値が返ってくるようになれば、そのほうが良いと思います。 1 については、本当は他のオプション同様 CREATE INDEX の引数で設定できればいいのでしょうが、手元の環境では bison のバージョン違いからかうまくできそうになかったので、とりあえずあきらめています。 以上です。 08/02/02 に Kazuho Oku<kazuh****@gmail*****> さんは書きました: > 奥です。 > > おそれいります。 > > 1カ所バグがあった (内部で一時テーブルが作成される場合に NULL access が発生していた) ので、それを修正したパッチです。 > #table->s->primary_key == 0 なのに table->key_info == NULL なケースがあるらしい > > 実用に近いケースということで、検索した結果を更新日時でソートして表示する SQL を実行してみましたが、 > > # 2ind を使わない場合 > mysql> select id,mtime,left(body,16) from tbl where match(body) > against ('+the' in boolean mode) order by mtime desc limit 10; > ... > 10 rows in set (0.12 sec) > > # join を利用して書いた場合 > mysql> select t3.id,t3.mtime,left(t4.body,16) from (select > t1.id,t2.mtime from tbl as t1 inner join tbl as t2 use index > (id_mtime) on t1.id=t2.id where match(t1.body) against ('+the' in > boolean mode) order by t2.mtime desc limit 10) as t3 inner join tbl as > t4 on t3.id=t4.id; > ... > 10 rows in set (0.05 sec) > > という感じでしたので、実用上の速度向上もありそうです (上の例は自己結合なので 2ind patch でもカバーできるものですが) > 。Tritonn 1.0.9 に更新したら、senna_2ind=ON でのベンチマークもとってみようと思います。 > > > 08/02/02 に Tetsuro IKEDA<ikdtt****@gmail*****> さんは書きました: > > こんばんは!池田です。 > > > > さっそくのpatch投稿ありがとうございます! > > めちゃ早いですね。。感激です。。。 > > > > ちょうどtritonn-1.0.9を出したところですので、次のバージョン(tritonn-1.1.0?)での > > 取り込みを視野に入れて調整してみたいとおもいます。 > > > > 08/02/01 に Kazuho Oku<kazuh****@gmail*****> さんは書きました: > > > 奥です。 > > > > > > MySQL のオプティマイザで他にもいろいろ気になることがあったので、勉強がてらパッチを書いてみました。 > > > > > > やっていることは単純で、 > > > > > > ・senna の key にプライマリキーを含める (8バイト以内の数字だった場合のみ) > > > ・オプティマイザの側で、取得カラムがプライマリキーのみか判定してフラグをたてる > > > ・取得カラムがプライマリキーのみの場合は senna のキーから値を返し、行データを読まない > > > (boolean mode のみ) > > > > > > ということです。手元の環境では、 > > > > > > select id from content_emkey where match(title,body) against > > > ('+the' in boolean mode); > > > > > > のようなクエリの所要時間が平均0.130秒から0.016秒に変化しました (メモリに載った状態で5回平均) 。実際には join > > > して使うことが多いでしょうから、そこまでの効果は望めないかもしれませんが、参照するワークセットが小さくなる > > > (同一メモリ量でより多くのデータを扱えるようになる) メリットも大きいと思います。 > > > > > > このパッチのメリットを整理すると、検索結果のプライマリキーにしか必要としない場合に無駄な行データ参照が発生しないため、 > > > > > > ・join した上で他のテーブルのカラムを利用して order by ... limit する際に場合の高速化/省メモリ化 > > > ・self join して order by ... limit することで、2nd index patch と同等の効果が期待できる > > > (ただし 2nd index patch より遅いと思います。ベンチとっていませんが) > > > > > > という感じになるかと思います。一方でデメリットは、 > > > > > > ・プライマリキーが8バイト以内の数字以外の場合に効果がない > > > ・1行あたり8バイト余計に空間を消費する > > > > > > というあたりになるかと思います。 > > > > > > 奥としては、 > > > > > > ・Item_func_match あたりのフラグの立て方をもう少し調整する必要がありそう > > > ・match の引数で subselect でインデックスを使うようなクエリを書くとやばいかも > > > ・boolean mode の relevance の計算を TF 風にしたい > > > (出現回数を fulltext の長さで割りたい) > > > > > > といった点があるので、まだもう少しいじるつもりですが、とりあえず、こちらにポストさせていただきたいと思います。 > > > > > > よろしくお願いいたします。 > > > > > > > > > 08/02/01 に Tetsuro IKEDA<te.ik****@jpta*****> さんは書きました: > > > > 奥さん、こちらでははじめまして:) 池田です。 > > > > > > > > ご報告ありがとうございます!! > > > > > > > > まだしっかり調べていないので正確なことは言えないですが、こうしたヘビーな > > > > 環境で使った場合の欠点はぜひぜひ改善していきたいと考えています。 > > > > > > > > 実際にご利用されている環境にて現れてきた性能問題としては他にも、、 > > > > ・大きなテーブルへの更新クエリにより参照クエリが長時間ブロックされる問題 > > > > (MyISAMを使用していることからくる欠点) > > > > ・更新クエリに対するCPUスケーラビリティが乏しい問題(これもMyISAM...) > > > > > > > > といったようなものを認識しています。 > > > > > > > > Tritonnの普及を促進したい自分としては、機能的な不具合だけでなく、 > > > > こうした問題にも積極的に取り組んでいきたいと考えております。 > > > > > > > > # もちろんpatchの寄贈とかも大歓迎です :) > > > > > > > > この件につきましては、こちらでも擬似環境を作って調べてみたいと思います。 > > > > その際にはいろいろ伺うこともあるかと思いますが、よろしくおねがいします。 > > > > > > > > > > > > > はじめまして、奥一穂と申します。 > > > > > > > > > > 仕事で Pathtraq というウェブサービスを開発していて、そのキーワード検索機能に Tritonn > > > > > を使わせていただいています。また、MySQL のストレージエンジンを開発していたりします (http://q4m.31tools.com/) > > > > > 。よろしくお願いいたします。 > > > > > > > > > > ところで、Tritonn の動作についてちょっと質問があるのですが、現状の Tritonn では、たとえば、 > > > > > > > > > > select id from content where match(body) against ('+test' in boolean mode); > > > > > > > > > > のようなクエリを投げた場合に、条件にマッチした全ての行データを MYD から読み込むと理解しています。 > > > > > > > > > > Pathtraq では、全文検索で得られた文書IDの一覧 (と tritonn の返す relevance と length(body)) > > > > > と、別テーブルに記録されているスコアの一覧を inner join ... order by して結果を返しているのですが、大量に MYD > > > > > へのアクセスが発生するため、実質的に MYD をメモリに載せておかないとサービスが提供できない感じになっています。 > > > > > #あるいは、約2倍程度のメモリが必要となっているということです > > > > > > > > > > 奥の理解では、この原因は2つあって、 > > > > > > > > > > ・sql/sql_select.cc の make_join_readinfo 関数で、他の型の場合に行われる最適化処理が JT_FT の場合に実行されない > > > > > ・そもそも MySQL の全文索引が、テーブルのプライマリキーではなく MYD ファイルのオフセットを記憶するようになっている > > > > > > > > > > というものです。 > > > > > > > > > > order by を予定するカラムと全文索引を同一テーブルに載せることができれば 2ind > > > > > パッチが有効になるパターンだと思うのですが、Pathtraq > > > > > の場合は、日ごとに異なるスコアテーブルがあるので、そのような対応は不可能です。また、他のユースケースにおいても、結合後に order by > > > > > をしたい、というのはあり得る話だと思います。 > > > > > > > > > > > > > > > 現象の説明が長くなってしまいましたが、この問題について、あるいは関連するようなバージョンアップは今後予定されていますでしょうか? > > > > > > > > > > 自分のケースに限って言えば、 > > > > > > > > > > ・プライマリキー等、必要なカラムを senna のキーのお尻にくっつけるようにする > > > > > ・senna のキーのお尻から読むような read_record を作る > > > > > ・read_record をセッション変数を用いて切り替えられるようにする > > > > > > > > > > といった感じでごまかしてしまえばオプティマイザに手を入れなくていいので楽なのですが、もっとちゃんとした解決策が検討されているのであれば、自分も何か協力できるかもしれませんし、メールする次第です。 > > > > > > > > > > よろしくお願いいたします。 > > > > > > > > > > > > > > > -- > > > > > Kazuho Oku > > > > > > > > > > _______________________________________________ > > > > > Tritonn-dev mailing list > > > > > Trito****@lists***** > > > > > http://lists.sourceforge.jp/mailman/listinfo/tritonn-dev > > > > > > > > ------------------------------ > > > > Tetsuro IKEDA > > > > Sumisho Computer Systems, Corp. > > > > http://www.scs.co.jp/mysql/ > > > > ------------------------------ > > > > > > > > _______________________________________________ > > > > Tritonn-dev mailing list > > > > Trito****@lists***** > > > > http://lists.sourceforge.jp/mailman/listinfo/tritonn-dev > > > > > > > > > > > > > -- > > > Kazuho Oku > > > > > > _______________________________________________ > > > Tritonn-dev mailing list > > > Trito****@lists***** > > > http://lists.sourceforge.jp/mailman/listinfo/tritonn-dev > > > > > > > > > > > > > _______________________________________________ > > Tritonn-dev mailing list > > Trito****@lists***** > > http://lists.sourceforge.jp/mailman/listinfo/tritonn-dev > > > > > -- > Kazuho Oku > > -- Kazuho Oku