Yuki Horikoshi
horik****@maste*****
2007年 6月 22日 (金) 23:55:19 JST
皆様はじめまして。堀越と申します。
実験的にtritonn-1.0.2.mysql-5.0.41.senna-1.0.5を利用させて頂いております。
複数カラムに対するOR検索にて顕著なパフォーマンスの悪化がありましたので
レポート・質問させてください。
CREATE TABLE TAB1 (COL1 TEXT,COL2 TEXT,FULLTEXT(COL1),FULLTEXT(COL2));
のようなテーブルに65万件の日本語データを投入しました。
以下はshow senna statusの結果です。
*************************** 1. row ***************************
Table: TAB1
Key_name: COL1
Column_name: COL1
Encoding: utf8
Index_type: NGRAM
Normalize: ON
Split_alpha: OFF
Split_digit: OFF
Split_symbol: OFF
Initial_n_segments: 512
Senna_keys_size: 644283
Senna_keys_file_size: 21045248
Senna_lexicon_size: 343130
Senna_lexicon_file_size: 12656640
Senna_inv_seg_size: 136220672
Senna_inv_chunk_size: 27660288
*************************** 2. row ***************************
Table: TAB1
Key_name: COL2
Column_name: COL2
Encoding: utf8
Index_type: NGRAM
Normalize: ON
Split_alpha: OFF
Split_digit: OFF
Split_symbol: OFF
Initial_n_segments: 512
Senna_keys_size: 527736
Senna_keys_file_size: 21045248
Senna_lexicon_size: 92521
Senna_lexicon_file_size: 8462336
Senna_inv_seg_size: 135172096
Senna_inv_chunk_size: 1708032
このデータに対して以下のクエリを投げました。
■単一カラムに対する検索の比較
SELECT * FROM TAB1 WHERE COL1 LIKE '%検索語%'; (1.11sec)
SELECT * FROM TAB1 WHERE MATCH(COL1) AGAINST ('検索語'); (0.01sec)
素晴らしい結果です。
■複数カラムに対するAND検索の比較
SELECT * FROM TAB1 WHERE COL1 LIKE '%検索語%' AND COL2 LIKE '%検索語%'; (1.10sec)
SELECT * FROM TAB1 WHERE MATCH(COL1) AGAINST ('検索語') AND MATCH(COL2) AGAINST ('検索語'); (0.06sec)
これも素晴らしい。
■複数カラムに対するOR検索の比較
SELECT * FROM TAB1 WHERE COL1 LIKE '%検索語%' OR COL2 LIKE '%検索語%'; (1.24 sec)
SELECT * FROM TAB1 WHERE MATCH(COL1) AGAINST ('検索語') OR MATCH(COL2) AGAINST ('検索語'); (3.68sec)
なぜか複数カラムに対するOR検索だけがパフォーマンスが悪いようです。
これはこういった物なのでしょうか?
Senna-dev569-585の池田様・うただ様のやりとりにあったように
show status like 'handle%';,vmstatも取得してみましたが、
like検索時とmatch-against検索時で同等の結果でした。
ちなみに、的外れかもしれませんが、
■UNIONクエリによる結合の比較
(SELECT * FROM TAB1 WHERE COL1 LIKE '%検索語%') UNION (SELECT * FROM TAB1 WHERE COL2 LIKE '%検索語%'); (1.99sec)
(SELECT * FROM TAB1 WHERE MATCH(COL1) AGAINST ('検索語')) UNION (SELECT * FROM TAB1 WHERE MATCH(COL2)
AGAINST ('検索語'));(0.06sec)
として上記遅延の回避はできましたが・・
また、ngram・mecabのどちらでも同様の結果でした。
問題点や解決法などあればご教示頂ければ幸いです。
何卒宜しくお願いいたします。
---
Yuki Horikoshi <horik****@maste*****>