Contents
  1. MySQL5.0.34+Senna1.0.1 on Linux2.6+AMD64
    1. テスト環境
    2. インデックスの構築
    3. 検索性能比較
    4. 更新性能比較
    5. まとめ

Tritonn性能検証

TritonnパッチはMySQLからSennaを使えるようにして、MySQL+Sennaによる高速全文検索を実現するためのものです。従って性能に関しては非常に重視しています。このページではTritonn開発者による性能検証の情報などを公開していく予定です。

性能面についてのバグが見つかった場合には、SourceForgeのバグ管理システムを利用して管理していく予定です。

MySQL5.0.34+Senna1.0.1 on Linux2.6+AMD64

OSC2007にて発表した内容です。

テスト環境

ハードウェア/ソフトウェア構成

以下のハードウェア/ソフトウェア構成にて行っています。

機種HP ProLiant 385
CPUAMD Dual Core Opteron 2.6GHz *2 (1MB L2 cache *2)
RAMDDR-SDRAM ECC PC3200 8GB
DISKSAS 2.5inch 10000rpm 72GB *4
RAIDBBWC付き 256MB
OSMiracle Linux 4.0 (Asianux 2.0) / Linux Kernel 2.6.9-11AXCustom
アーキテクチャx86_64 (EM64T/AMD64)
MySQLver5.0.34
Sennaver1.0.1
Tritonnver1.0.0の少し前
チューニング値

以下の値を使用しています。

mysqlmyisam_sort_buffer_size1024MB
mysqlkey_buffer_size1024MB
sennainitial_n_segments2048
テストに使用したデータ

日本語版Wikipediaのダンプデータ から記事本体のテキストデータを抽出したもの。

以下のテーブルに格納した所、約57万行、MYDファイルサイズ1.4GB、平均行長2300バイトになった。

CREATE TABLE t1 (
  c1 INT PRIMARY KEY AUTO_INCREMENT,
  c2 TEXT
) ENGINE = MyISAM DEFAULT CHARSET utf8;
負荷ツール

mbenchをMySQL C APIを使用してC言語で再実装したもの。表に出せるクオリティではないのでまだOSS化はしていません。。。

ノード構成

サーバ用として上記のハードウェア1台と、クライアント用としてThinkPad T43を1台の構成。

インデックスの構築

前提条件として、テーブル作成、データ格納を行った後、以下のSQL文を実行して計測。

CREATE FULLTEXT INDEX ft USING NORMALIZE, 2048 ON t1(c2);
CREATE FULLTEXT INDEX ft USING NGRAM, NORMALIZE, 2048 ON t1(c2);

これにより、データサイズ1.4GB/57万行の時のmecabとngramそれぞれのインデックス構築速度が分かる。

結果

ファイルサイズはngramの方が大きくなってしまうものの、速度自体はこちらの方が速い。

index_type要した時間スループットSENファイルのサイズ合計SENファイル内の語彙数
mecab18分22秒513.7行/秒1.47GB417万語
ngram14分32秒649.2行/秒2.13GB523万語
捕捉事項
  • myisam_sort_buffer_sizeを大きくすると性能UP
  • initial_n_segmentsを大きくすると性能UP
  • myisam_repair_threadsは無関係

検索性能比較

あらかじめ10接続を作成しておき、mecab、ngram、インデックス無しのテーブルに対して、2分間、ラッシュ検索を実施。

mecab/ngramに対しては以下のSQL文を繰り返し実行。いわゆる全文検索。

SELECT COUNT(*) FROM t1 WHERE MATCH(c2) AGAINST("キーワード");

インデックス無しについては以下のSQL文を繰り返し実行。いわゆる部分一致検索。

SELECT COUNT(*) FROM t1 WHERE c2 LIKE '%キーワード%';

このとき使用するキーワードは、あらかじめ用意した約6万の日本語の名詞の中から各接続ごとに1万個選んでおき、それぞれがその選んでおいたものを使用している。

※ただし、ここで使用している名詞そのものはmecab-ipadicから抽出しているので、mecabに有利な結果が出やすいというのも考慮する必要あり。

結果(複数回計測した値の平均値)

※OSのファイルキャッシュの影響を著しく受けるため、OSのファイルキャッシュに十分乗り切った状態で計測している。

index_typeスループット平均レスポンス相対値
mecab3190.7 クエリ/秒3.1 ミリ秒10293 倍
ngram1235.3 クエリ/秒8.1 ミリ秒3985 倍
インデックス無し0.31 クエリ/秒31.2 秒1

部分一致検索(LIKE演算子)が圧倒的に遅い。データ量が数MBなら両者の差は少ないかもしれないが、ある程度以上大きくなってくると部分一致検索では太刀打が出来なくなる。

mecabの方がngramに比べて断然速い。とはいえ、ngramのほうもスループット/平均レスポンスともに十分実用可能な範囲と思われる。

補足
  • ラッシュ時の同時接続数を1〜増やしていくと、CPUコア数まではスケールする。
  • さらに同時接続数を増やすと、スループットが伸び無い分、平均レスポンスが低下していく。

更新性能比較

あらかじめ10接続を作成しておき、mecab、ngram、インデックス無しのテーブルに対して、2分間、ラッシュ更新を実施。

以下のSQL文を繰り返し実行。

INSERT INTO t1 (c2) SELECT c2 FROM t1_copy WHERE c1 = キー;

t1_copyはt1テーブルと同じデータを持つ別のテーブル。ここでも、日本語の文章として意味のあるものを入力データに使用する必要があったため、bestな案ではないが、この方法を採用した。"キー"には事前にランダムで選んでおいた数値(t1_copyに実在する数値)を使用。

結果

※OSのファイルキャッシュの影響を著しく受けるため、OSのファイルキャッシュに十分乗り切った状態で計測している。

index_typeスループット平均レスポンス相対値
mecab246.7 行/秒43.7 ミリ秒0.38 倍
ngram254.3 行/秒40.5 ミリ秒0.40 倍
インデックス無し641.2 行/秒15.6 ミリ秒1

インデックス無しの時に比べると、mecab/ngram双方とも半分弱に低下。

今回は平均行長が2300バイトもあるため、そもそもかなり重たいINSERTであった。平均行長がもっと短い場合には、絶対値はそれぞれもっと向上する。

補足
  • MyISAMでは更新時に1CPUしか処理が行われないため、更新処理についてはマルチコアのメリットは受けられない。

まとめ

MySQL+Sennaを使うと、MySQLのみの場合に比べて全文検索処理についておよそ以下のような傾向があると考えられる。

  • 検索性能が数千倍にあがる
  • 更新性能が半分以下に落ちる
Last modified: 2009-03-23 Attached files total: 404KB