MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

50
MySQL-5.6で始める全文検索 ~InnoDB FTS編~ MySQL Casual Talks #4 Kentaro Yoshida @yoshi_ken

description

MySQL Casual Talks Vol.4 でのライトニングトークに利用した資料です。 MySQL-5.6.4より「InnoDB FTS」としてInnoDBで全文検索機能が加わりました。 この全文検索機能を利用し、日本語の全文検索エンジンとしての可能性を探ります。 ブログ記事はこちらです。 http://y-ken.hatenablog.com/entry/mysql-casual-talks-vol4-innodb-fts

Transcript of MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

Page 1: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

MySQL-5.6で始める全文検索~InnoDB FTS編~

MySQL Casual Talks #4 Kentaro Yoshida

@yoshi_ken

Page 2: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

本日の流れ自己紹介今回のテーマMySQL-5.6時代の全文検索プロダクト紹介全文検索の動作デモベンチマークまとめ次回予告とお知らせ

Page 3: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

自己紹介よしけんさん の中の人研究開発系のインフラエンジニア興味分野MySQL, Fluentd, Ruby, KVM, DRBD, Nginx, Redis, MongoDB, etc...

Page 4: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

今回のテーマ

MySQL-5.6.4のInnoDBでは全文検索が可能となった

しかしMeCabTokenizerどころかNgramにすら非対応

スペース区切りなら検索できる!(ポジティブ思考)

自前で分かち書きすれば動くのでは?でも速度は?

こんな状況に果敢に挑戦したレポートです

Page 5: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

MySQL-5.6時代の全文検索プロダクト紹介(mroonga / InnoDB-FTS / SphinxSE)

Page 8: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

SphinxSEhttp://sphinxsearch.com/

これは別物

Page 9: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

mroonga (groonga)

Tritonn (Senna) の後継プロダクト

参照ロックフリー

完全転置索引を採用

MeCabやN-gramでの分かち書きに対応

N-gramおよびCJKに対応

Page 10: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

InnoDB FTS (FullTextSearch)

MySQL-5.6.4から正式対応(しかも標準)

参照ロックフリー

mroonga (groonga) 同様に完全転置索引を採用

空白区切りの単語のみ検索可能

現状、N-gramおよびCJKには非対応

Page 11: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

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

Page 12: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

全文検索デモ (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 ;

Page 13: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

全文検索デモ (mroonga)データ登録

INSERT INTO search_with_mroonga (subject, content) VALUES ( ‘MySQL’, ’MySQL(マイエスキューエル)は、オラクルが開発するRDBMS(リレーショナルデータベースを管理、運用するためのシステム)の実装の一つである。’ );

Page 14: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

全文検索デモ (mroonga)データ検索

SELECT * FROM search_with_mroonga WHERE MATCH(subject,content) AGAINST('+オラクル' IN BOOLEAN MODE);

Page 15: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

全文検索デモ (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 ;

Page 16: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

全文検索デモ (InnoDB FTS)分かち書き with CLI

echo "MySQL(マイエスキューエル)は、オラクルが開発するRDBMS(リレーショナルデータベースを管理、運用するためのシステム)の実装の一つである。" | mecab --output-format-type wakati

Page 17: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

全文検索デモ (InnoDB FTS)分かち書き with Ruby

# -*- encoding: utf-8 -*-require 'MeCab'wakati = MeCab::Tagger.new('-O wakati')puts wakati.parse('本日も良い天気です')

Page 18: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

全文検索デモ (InnoDB FTS)データ登録

INSERT INTO search_with_innodb (subject, content) VALUES ( ‘MySQL’, ’MySQL ( マイエスキューエル ) は 、 オラクル が 開発 する RDBMS ( リレーショナル データベース を 管理 、 運用 する ため の システム ) の 実装 の 一つ で ある 。’ );

Page 19: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

全文検索デモ (InnoDB FTS)データ検索

SELECT * FROM search_with_innodbWHERE MATCH(subject,content) AGAINST('+オラクル' IN BOOLEAN MODE);

Page 20: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

ベンチマークOracle公式MySQL-5.6.10にmroonga-3.02を入れ、mroongaとInnoDB-FTSの性能比較試験を行う

書き込み性能

全文検索性能

利用マシン

Intel Xeon L5520 2.27GHz, 16GB MemoryCentOS 6.4 (x86_64)

Page 21: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

ベンチマーク

テーブル構成

mroonga ストレージモード

インデックス作成時のオプションにて分かち書き方法を指定する

search_with_mroonga_ngramsearch_with_mroonga_mecab

Page 22: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

ベンチマーク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 ;

Page 23: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

ベンチマーク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 ;

Page 24: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

ベンチマーク

テーブル構成

InnoDB FTS分かち書き機能を内蔵していないため、事前にRubyプログラムにて分かち書きを行う

search_with_innodb_ngramsearch_with_innodb_mecab

Page 25: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

ベンチマーク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 ;

Page 26: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

ベンチマーク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 ;

Page 27: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

ベンチ:更新性能

5万件×15回のINSERT所要秒数を計測し、件数が増えることでの性能劣化を測ります

サンプルデータには、dbpedia.org より入手したWikipedia日本語版の75万件の記事を利用します

Page 28: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

ベンチ:更新性能tsvデータの容量ngramはbi-gramのため、2倍以上の容量となります。

$ ls -sh wikipedia_*.tsv408M wikipedia_mecab.tsv798M wikipedia_ngram.tsv345M wikipedia_plain.tsv

Page 29: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

ベンチ:更新性能クエリ例

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);

Page 30: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

ベンチ:更新性能

0

1000

2000

3000

4000

75万件の登録所要時間(秒)

3054.54

329.8629.57178.01

mroonga mecabInnoDB FTS mecabmroonga ngramInnoDB FTS ngram

Page 31: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

tsvデータを5万行毎のファイル15個に分割し、LOAD DATA LOCAL INFILEを立て続けに行った際、速度がどのように変化していくかを計測しました。

Page 32: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

ベンチ:更新性能

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万件単位での書き込み所要時間(秒)

Page 33: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

5万件単位での書き込み所要時間を計測したところ、InnoDB FTS ngramはダントツで遅いため、グラフから外し、MeCabのみで比較します。

Page 34: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

ベンチ:更新性能

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万件単位での書き込み所要時間(秒)

Page 35: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

ベンチ:更新性能

結果

mroongaがダントツで最速

InnoDB FTSもMeCabデータを入れるなら業務要件次第では実用的な範囲

Page 36: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

ベンチ:全文検索性能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

Page 37: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

ベンチ:全文検索性能クエリ例

SELECT SQL_NO_CACHE count(*) FROM search_with_innodb_mecab WHERE match(subject,content) against('+表参道' IN BOOLEAN MODE);

Page 38: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

ベンチ:全文検索性能

1ワード

0 50 100 150 200

61.638

187.944

55.152

163.824

mroonga mecabInnoDB FTS mecabmroonga ngramInnoDB FTS ngram

75万レコードに対して5万単語を順次SELECTした際の実行所要時間(秒)

Page 39: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

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

Page 40: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

まとめMySQL-5.6.4 以降で使えるようになったInnoDB FTSは意外と実用的です

InnoDB FTSを使うならアプリ側でMeCabを用いた分かち書きをしましょう

MySQL単体で全文検索を実現したい場合のmroonga以外の選択肢が、1つ増えました

Page 41: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

最後に

詳細な解説記事は追ってアップします。その際はTwitterにてお知らせします。

https://twitter.com/yoshi_ken

http://d.hatena.ne.jp/yoshi-ken/

Page 42: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

次回予告

Page 43: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

次回予告

Tritonn (MySQL-5.0.87+Senna)からのmroonga (MySQL-5.6) 移行ガイド

Page 44: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

お知らせ

Page 45: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

あたりまえを、発明しよう。

Page 46: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」
Page 47: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」
Page 48: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」
Page 49: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」
Page 50: MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」

ご清聴ありがとうございました。