mysql casual talks vol.4 「mysql-5.6で始める全文検索 〜innodb fts編〜」
DESCRIPTION
MySQL Casual Talks Vol.4 でのライトニングトークに利用した資料です。 MySQL-5.6.4より「InnoDB FTS」としてInnoDBで全文検索機能が加わりました。 この全文検索機能を利用し、日本語の全文検索エンジンとしての可能性を探ります。 ブログ記事はこちらです。 http://y-ken.hatenablog.com/entry/mysql-casual-talks-vol4-innodb-ftsTRANSCRIPT
MySQL-5.6で始める全文検索~InnoDB FTS編~
MySQL Casual Talks #4 Kentaro Yoshida
@yoshi_ken
本日の流れ自己紹介今回のテーマMySQL-5.6時代の全文検索プロダクト紹介全文検索の動作デモベンチマークまとめ次回予告とお知らせ
自己紹介よしけんさん の中の人研究開発系のインフラエンジニア興味分野MySQL, Fluentd, Ruby, KVM, DRBD, Nginx, Redis, MongoDB, etc...
今回のテーマ
MySQL-5.6.4のInnoDBでは全文検索が可能となった
しかしMeCabTokenizerどころかNgramにすら非対応
スペース区切りなら検索できる!(ポジティブ思考)
自前で分かち書きすれば動くのでは?でも速度は?
こんな状況に果敢に挑戦したレポートです
MySQL-5.6時代の全文検索プロダクト紹介(mroonga / InnoDB-FTS / SphinxSE)
mroongahttp://mroonga.github.io/ja/docs/characteristic.html
InnoDB Full-Text Searchhttps://blogs.oracle.com/mysqlinnodb/entry/innodb_full_text_search_is
mroonga (groonga)
Tritonn (Senna) の後継プロダクト
参照ロックフリー
完全転置索引を採用
MeCabやN-gramでの分かち書きに対応
N-gramおよびCJKに対応
InnoDB FTS (FullTextSearch)
MySQL-5.6.4から正式対応(しかも標準)
参照ロックフリー
mroonga (groonga) 同様に完全転置索引を採用
空白区切りの単語のみ検索可能
現状、N-gramおよびCJKには非対応
Sphinx SE (Search Engine)概要 by wikipediahttp://en.wikipedia.org/wiki/Sphinx_(search_engine)
日本語解説 by IBMhttp://www.ibm.com/developerworks/jp/opensource/library/os-sphinx/?cmp=dw&cpb=dwope&ct=dwrss&cr=dwrss&ccy=jp&csr=120911
storage plugin対応http://sphinxsearch.com/docs/current.html#sphinxse-using
リアルタイムインデックス非対応(疑惑)http://www.slideshare.net/conmame/ss-12117195/9
ベンチマークhttp://www.percona.com/files//presentations/opensql2008_sphinx.pdfhttp://www.slideshare.net/billkarwin/practical-full-text-search-with-my-sql
インストール方法http://www.howtoforge.com/sphinx-as-mysql-storage-engine-sphinxse
日本語 (CJK) 対応状況http://www.ivinco.com/blog/using-sphinx-search-engine-with-chinese-japanese-and-korean-language-documents/
MySQL-5.6.10対応状況http://sphinxsearch.com/bugs/view.php?id=1419
全文検索デモ (mroonga)テーブル作成
CREATE TABLE search_with_mroonga ( id INT PRIMARY KEY AUTO_INCREMENT, subject TEXT, content TEXT, FULLTEXT INDEX (subject,content) ) ENGINE = mroonga DEFAULT CHARSET utf8 collate utf8_unicode_ci ;
全文検索デモ (mroonga)データ登録
INSERT INTO search_with_mroonga (subject, content) VALUES ( ‘MySQL’, ’MySQL(マイエスキューエル)は、オラクルが開発するRDBMS(リレーショナルデータベースを管理、運用するためのシステム)の実装の一つである。’ );
全文検索デモ (mroonga)データ検索
SELECT * FROM search_with_mroonga WHERE MATCH(subject,content) AGAINST('+オラクル' IN BOOLEAN MODE);
全文検索デモ (InnoDB FTS)テーブル作成
CREATE TABLE search_with_innodb ( id INT PRIMARY KEY AUTO_INCREMENT, subject TEXT, content TEXT, FULLTEXT INDEX (subject,content)) ENGINE=InnoDB DEFAULT CHARSET utf8 collate utf8_unicode_ci ;
全文検索デモ (InnoDB FTS)分かち書き with CLI
echo "MySQL(マイエスキューエル)は、オラクルが開発するRDBMS(リレーショナルデータベースを管理、運用するためのシステム)の実装の一つである。" | mecab --output-format-type wakati
全文検索デモ (InnoDB FTS)分かち書き with Ruby
# -*- encoding: utf-8 -*-require 'MeCab'wakati = MeCab::Tagger.new('-O wakati')puts wakati.parse('本日も良い天気です')
全文検索デモ (InnoDB FTS)データ登録
INSERT INTO search_with_innodb (subject, content) VALUES ( ‘MySQL’, ’MySQL ( マイエスキューエル ) は 、 オラクル が 開発 する RDBMS ( リレーショナル データベース を 管理 、 運用 する ため の システム ) の 実装 の 一つ で ある 。’ );
全文検索デモ (InnoDB FTS)データ検索
SELECT * FROM search_with_innodbWHERE MATCH(subject,content) AGAINST('+オラクル' IN BOOLEAN MODE);
ベンチマークOracle公式MySQL-5.6.10にmroonga-3.02を入れ、mroongaとInnoDB-FTSの性能比較試験を行う
書き込み性能
全文検索性能
利用マシン
Intel Xeon L5520 2.27GHz, 16GB MemoryCentOS 6.4 (x86_64)
ベンチマーク
テーブル構成
mroonga ストレージモード
インデックス作成時のオプションにて分かち書き方法を指定する
search_with_mroonga_ngramsearch_with_mroonga_mecab
ベンチマークsearch_with_mroonga_ngram
CREATE TABLE search_with_mroonga_ngram ( id INT PRIMARY KEY AUTO_INCREMENT, subject TEXT, content TEXT, FULLTEXT (subject,content)) ENGINE=mroonga DEFAULT CHARSET utf8 collate utf8_unicode_ci ;
ベンチマークsearch_with_mroonga_mecab
CREATE TABLE search_with_mroonga_mecab ( id INT PRIMARY KEY AUTO_INCREMENT, subject TEXT, content TEXT, FULLTEXT (subject,content) COMMENT 'parser "TokenMecab"') ENGINE=mroonga DEFAULT CHARSET utf8 collate utf8_unicode_ci ;
ベンチマーク
テーブル構成
InnoDB FTS分かち書き機能を内蔵していないため、事前にRubyプログラムにて分かち書きを行う
search_with_innodb_ngramsearch_with_innodb_mecab
ベンチマークsearch_with_innodb_ngram
CREATE TABLE search_with_innodb_ngram ( id INT PRIMARY KEY AUTO_INCREMENT, subject TEXT, content TEXT, FULLTEXT (subject,content)) ENGINE=InnoDB DEFAULT CHARSET utf8 collate utf8_unicode_ci ;
ベンチマークsearch_with_innodb_mecab
CREATE TABLE search_with_innodb_mecab ( id INT PRIMARY KEY AUTO_INCREMENT, subject TEXT, content TEXT, FULLTEXT (subject,content)) ENGINE=InnoDB DEFAULT CHARSET utf8 collate utf8_unicode_ci ;
ベンチ:更新性能
5万件×15回のINSERT所要秒数を計測し、件数が増えることでの性能劣化を測ります
サンプルデータには、dbpedia.org より入手したWikipedia日本語版の75万件の記事を利用します
ベンチ:更新性能tsvデータの容量ngramはbi-gramのため、2倍以上の容量となります。
$ ls -sh wikipedia_*.tsv408M wikipedia_mecab.tsv798M wikipedia_ngram.tsv345M wikipedia_plain.tsv
ベンチ:更新性能クエリ例
LOAD DATA LOCAL INFILE '/path/to/wikipedia_mecab.tsv' INTO TABLE search_with_innodb_mecab FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n' (id,subject,content);
ベンチ:更新性能
0
1000
2000
3000
4000
75万件の登録所要時間(秒)
3054.54
329.8629.57178.01
mroonga mecabInnoDB FTS mecabmroonga ngramInnoDB FTS ngram
tsvデータを5万行毎のファイル15個に分割し、LOAD DATA LOCAL INFILEを立て続けに行った際、速度がどのように変化していくかを計測しました。
ベンチ:更新性能
0
100
200
300
400
50k 100k 150k 200k 250k 300k 350k 400k 450k 500k 550k 600k 650k 700k 750k
mroonga mecabInnoDB FTS mecabmroonga ngramInnoDB FTS ngram
5万件単位での書き込み所要時間(秒)
5万件単位での書き込み所要時間を計測したところ、InnoDB FTS ngramはダントツで遅いため、グラフから外し、MeCabのみで比較します。
ベンチ:更新性能
0
15
30
45
60
50k 100k 150k 200k 250k 300k 350k 400k 450k 500k 550k 600k 650k 700k 750k
mroonga mecabInnoDB FTS mecab
5万件単位での書き込み所要時間(秒)
ベンチ:更新性能
結果
mroongaがダントツで最速
InnoDB FTSもMeCabデータを入れるなら業務要件次第では実用的な範囲
ベンチ:全文検索性能5万件の単語を直列に全文検索する際の所要秒数を計測し、全文検索性能の比較を行います
単語データは、MeCab-IPA辞書の名詞版(固有名詞・地域)から5万件を抽出しています
$ nkf -w src/mecab-ipadic-2.7.0-20070801/Noun.place.csv | cut -d"," -f1 | sort | uniq | sort -R | head -n 50000
ベンチ:全文検索性能クエリ例
SELECT SQL_NO_CACHE count(*) FROM search_with_innodb_mecab WHERE match(subject,content) against('+表参道' IN BOOLEAN MODE);
ベンチ:全文検索性能
1ワード
0 50 100 150 200
61.638
187.944
55.152
163.824
mroonga mecabInnoDB FTS mecabmroonga ngramInnoDB FTS ngram
75万レコードに対して5万単語を順次SELECTした際の実行所要時間(秒)
5万単語を用意して直列に順次検索を行いましたが、
該当件数が0件となる単語が半数ある事を補足します。
search_with_mroonga_mecab: Noresult count: 33658search_with_innodb_mecab: Noresult count: 24950 search_with_mroonga_ngram: Noresult count: 23129search_with_innodb_ngram: Noresult count: 35500
まとめMySQL-5.6.4 以降で使えるようになったInnoDB FTSは意外と実用的です
InnoDB FTSを使うならアプリ側でMeCabを用いた分かち書きをしましょう
MySQL単体で全文検索を実現したい場合のmroonga以外の選択肢が、1つ増えました
最後に
詳細な解説記事は追ってアップします。その際はTwitterにてお知らせします。
https://twitter.com/yoshi_ken
http://d.hatena.ne.jp/yoshi-ken/
次回予告
次回予告
Tritonn (MySQL-5.0.87+Senna)からのmroonga (MySQL-5.6) 移行ガイド
お知らせ
あたりまえを、発明しよう。
ご清聴ありがとうございました。