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*****>