[groonga-dev,00978] Re: mroonga検索スコア順のソートについて

Back to archive index

Kouhei Sutou kou****@clear*****
2012年 7月 5日 (木) 16:21:04 JST


須藤です。

In <CAEQj****@mail*****>
  "[groonga-dev,00977] mroonga検索スコア順のソートについて" on Thu, 5 Jul 2012 14:14:22 +0900,
  中谷宗嵩 <nakatani_munet****@flyin*****> wrote:

> 【テーブル】
> id・title・atuthor・publisherの4つのカラムを持つ、bookというテーブルを使用。

もしよかったらテーブル定義(create table (...))を教えて頂い
てもよいでしょうか?インデックスの張り方を確認したいのと、手
元でも試してみたいというのが理由です。

> (a)
> SELECT * FROM book WHERE MATCH(title,author,publisher) AGAINST("キーワード"
> in boolean mode) ORDER BY MATCH(title) AGAINST("キーワード" in boolean
> mode) , MATCH(author) AGAINST("キーワード" in boolean mode) ,
> MATCH(publisher) AGAINST("キーワード" in boolean mode);
> 
> これでSQLは通ったのですが、得られた結果が、
> ORDER BY句をつけないときと比べ、明らかに減少してしまいました。
> これは恐らく、WHERE句に使用していない条件を、
> ORDER BY句に使用したのが原因だと考えられたので、続いて(b)を実行しました。

うーん、ORDER BYをつけたかどうかで結果が少なくなることはない
と思うんですよねぇ。。。どうしてかしら。
できれば手元でも試してみたいです。


> (b)
> SELECT * FROM book WHERE MATCH(title) AGAINST("キーワード" in boolean mode)
> OR MATCH(author) AGAINST("キーワード" in boolean mode) OR MATCH(publisher)
> AGAINST("キーワード" in boolean mode) ORDER BY MATCH(title) AGAINST("キーワード"
> in boolean mode) , MATCH(author) AGAINST("キーワード" in boolean mode) ,
> MATCH(publisher) AGAINST("キーワード" in boolean mode);
> 
> こちらで、目的の結果を得ることが出来ました。
> ただし、(b)のSQLは冗長で、パフォーマンス的にもあまり良くないように思われます。

たしかに、検索回数が増えますね。
マルチカラムインデックスでは1回の検索で済んだものが3回の検索
になります。

が、ORDER BYでそれぞれのカラム毎のスコアを使いたいというので
あれば、どうせ3回検索しなければいけないので、それを踏まえると
パフォーマンス的にはむしろ(b)の方が(a)よりよさそうな気がしま
す。

というのは、同じSQL内に同じMATCH AGAINSTが複数あっても実際に
は1度しか検索しないからです。(a)では以下のように4つのMATCH
AGAINSTがあり、すべて違うので4回検索します。

  * MATCH(title,author,publisher) AGAINST("キーワード" in boolean mode)
  * MATCH(title) AGAINST("キーワード" in boolean mode) 
  * MATCH(author) AGAINST("キーワード" in boolean mode)
  * MATCH(publisher) AGAINST("キーワード" in boolean mode)

一方、(b)は以下のように6つのMATCH AGAINSTがありますが、重複
を除くと3種類になるので、3回しか検索しません。

  * MATCH(title) AGAINST("キーワード" in boolean mode)
  * MATCH(author) AGAINST("キーワード" in boolean mode)
  * MATCH(publisher) AGAINST("キーワード" in boolean mode)
  * MATCH(title) AGAINST("キーワード" in boolean mode)
  * MATCH(author) AGAINST("キーワード" in boolean mode)
  * MATCH(publisher) AGAINST("キーワード" in boolean mode)

よって、(b)の方がパフォーマンスがよさそうです。

> 【質問】
> (1)目的の検索結果を取得するために、(b)以外で、より効率的なSQL文を書くことは可能でしょうか。
>   ((a)のように、マルチカラムインデックスを使う方法で実現出来るとうれしいのですが・・・。)

冗長ですがORDER BYの数を減らせないということのようなので、
(b)が一番効率がよさそうです。

> (2)mroongaをパフォーマンスチューニングするための設定ファイルなどは存在するのでしょうか。

何かのバッファサイズを指定する、とかそういう類の設定というこ
とですよね。実は、そういうのは存在しないのです。今後、できる
かもしれませんが、今のところはありません。

-- 
須藤 功平 <kou****@clear*****>
株式会社クリアコード <http://www.clear-code.com/> (03-6231-7270)

groongaサポート:
  http://groonga.org/ja/support/
プログラミングが好きなソフトウェア開発者を募集中:
  http://www.clear-code.com/recruitment/




groonga-dev メーリングリストの案内
Back to archive index