Rabbit Slide Show

MroongaとPGroonga

2016-02-09

Description

MySQL・PostgreSQLでGroonga(Mroonga・PGroonga)を使って日本語全文検索する方法とその特徴を紹介します。

Text

Page: 1

Mroonga
PGroonga
と
Groongaを使って
MySQLとPostgreSQLで日本語全文検索
クリアコード
須藤功平
MySQLとPostgreSQLと日本語全文検索
2016-02-09
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 2

Mroonga・PGroonga
Mroonga(むるんが)
MySQLに
高速日本語全文検索機能を追加する
プロダクト
PGroonga(ぴーじーるんが)
PostgreSQLに
高速日本語全文検索機能を追加する
プロダクト
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 3

すごい!使いたい!
インストールして!
え。。。組み込みじゃないの。。。
(MariaDBにはMroongaは組み込まれています!)
パッケージあるから簡単だよ!
クラウドサービスで使えない。。。
(クラウドサービスに入っていれば…!)
HerokuのPostgreSQLにPGroonga入れて!とお願いだ!
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 4

使いたい!?
HerokuのPostgreSQLで
PGroongaを使えるなら
Herokuを使いたい!
#herokujp
↑と思うならtweet!
(Herokuの人が観測します。)
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 5

高速?
ベンチマーク!
対象:Wikipedia日本語版
レコード数:約185万件
データサイズ:約7GB
メモリー4GB・SSD250GB (ConoHa)
https://github.com/groonga/wikipedia-search/issues/4
(他人のベンチマークは参考程度)
(検討時はちゃんと実際の環境でベンチマークをとろう!)
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 6

速さ:検索1
キーワード:テレビアニメ
(ヒット数:約2万3千件)
InnoDB ngram
InnoDB MeCab
Mroonga:1
pg_bigm
PGroonga:2
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
3m2s
6m20s
0.11s
4s
0.29s
Powered by Rabbit 2.1.9

Page: 7

速さ:検索2
キーワード:データベース
(ヒット数:約1万7千件)
InnoDB ngram
InnoDB MeCab:1
Mroonga:2
pg_bigm
PGroonga:3
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
36s
0.03s
0.09s
2s
0.17s
Powered by Rabbit 2.1.9

Page: 8

速さ:検索3
キーワード:PostgreSQL OR MySQL
(ヒット数:約400件)
InnoDB ngram
N/A(エラー)
InnoDB MeCab:1
0.005s
Mroonga:2
0.028s
pg_bigm
0.185s
PGroonga:3
0.063s
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 9

速さ:検索4
キーワード:日本
(ヒット数:約63万件)
InnoDB ngram
InnoDB MeCab
Mroonga:1
pg_bigm:2
PGroonga
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
1.3s
1.3s
0.21s
0.84s
1s
Powered by Rabbit 2.1.9

Page: 10

速さ:検索まとめ
Mroonga・PGroonga
安定して速い
InnoDB FTS MeCab・pg_bigm
ハマれば速い
InnoDB FTS ngram
安定して遅い
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 11

使いたい!?
HerokuのPostgreSQLで
PGroongaを使えるなら
Herokuを使いたい!
#herokujp
↑と思うならtweet!
(Herokuの人が観測します。)
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 12

速さ:データロード
約185万件・約7GB・SSD
InnoDB ngram
6m51s
InnoDB MeCab
6m22s
Mroonga:3
5m45s
pg_bigm:1
5m14s
PGroonga:2
5m22s
MySQLはbinlog有効、PostgreSQLはWAL有効
InnoDBはどっちも同じ処理
pg_bigmとPGroongaもどっちも同じ処理
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 13

速さ:インデックス作成
約185万件・約7GB・SSD
InnoDB ngram
3h06m58s
InnoDB MeCab
2h41m55s
Mroonga:1
22m24s
pg_bigm
3h43m23s
PGroonga:2
54m34s
MySQLはbinlog有効、PostgreSQLはWAL有効
バルクインデックス作成
=データ投入後インデックス作成
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 14

速さ:ロードまとめ
データロードは大差ない
インデックス作成は大差
Mroonga・PGroongaは分単位
InnoDB・pg_bigmは時間単位
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 15

使いたい!?
HerokuのPostgreSQLで
PGroongaを使えるなら
Herokuを使いたい!
#herokujp
↑と思うならtweet!
(Herokuの人が観測します。)
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 16

サイズ:データ
InnoDB ngram
InnoDB MeCab
Mroonga
pg_bigm:2
PGroonga:1
10GB
10GB
8.2GB
5.1GB
4.3GB
InnoDBはどっちも同じ
pg_bigmとPGroongaはどっちも同じはずだけど…
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 17

サイズ:インデックス
InnoDB ngram
InnoDB MeCab:1
Mroonga:1
pg_bigm:3
PGroonga
12GB
6GB
6GB
7GB
10GB
InnoDBは一時ファイル(何十GB単位)を作る
PGroongaは元データ(8GB)のコピーもLZ4圧縮して持っている
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 18

サイズ:まとめ
データサイズ
PostgreSQLは元データより小さめ
InnoDBは元データより大きめ
インデックスサイズ
InnoDB MeCabは小さめ
(ヒント:形態素解析ベースの方が小さくなる)
Mroonga・pg_bigmはN-gramなのに
InnoDB MeCabと同じくらい
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 19

高速?
ベンチマークで
確認
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 20

Mroonga・PGroonga
Mroonga(むるんが)
MySQLに
高速日本語全文検索機能を追加する
プロダクト
PGroonga(ぴーじーるんが)
PostgreSQLに
高速日本語全文検索機能を追加する
プロダクト
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 21

実現方法
Mroonga(むるんが)
MySQLに
Groonga(ぐるんが)を組み込み
PGroonga(ぴーじーるんが)
PostgreSQLに
Groonga(ぐるんが)を組み込み
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 22

Groonga
国産の高速全文検索エンジン
日本語バッチリ
ライブラリーとして使える
組み込みやすい
マルチスレッド対応
(MySQL組み込み時にうれしい)
マルチプロセス対応
(PostgreSQL組み込み時にうれしい)
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 23

組み込み方針
Groongaをできるだけ活かす
使い勝手はMySQL・PostgreSQL
に寄せる
↓
SQLで使えるGroonga
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 24

ポジション
全文検索エンジンの性能
(速さ・精度・関連機能など)
InnoDB FTS
pg_bigm
MySQLらしさ
PostgreSQLらしさ
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 25

SQLで使えるGroonga
Groongaのフル機能は諦める
速度など譲れない部分はがんばる
その分、使いやすさを重視
使いやすさ1=
MySQL・PostgreSQLとなじんでいる
使いやすさ2=
MySQL・PostgreSQLの不便を解消
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 26

なじみ度:Mroonga
インデックス作成:MySQLと同じ
CREATE TABLE ... (
...,
FULLTEXT INDEX (column)
) ENGINE=Mroonga;
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 27

なじみ度:Mroonga
全文検索:MySQLと同じ
SELECT * FROM ...
WHERE
MATCH(column)
AGAINST('キーワード'
IN BOOLEAN MODE);
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 28

不便解消:Mroonga
デフォルトOR→AND
-- ↓AまたはBが含まれていればマッチ
AGAINST('A B' IN BOOLEAN MODE);
AGAINST('+A +B' IN BOOLEAN MODE);
-- ↑↓AとBが含まれていればマッチ
-- ↓Mroongaの拡張
AGAINST('*D+ A B' IN BOOLEAN MODE);
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 29

不便解消:Mroonga
重み指定
-- titleかcontentにAがあればマッチ
-- (便利。PostgreSQLではできない。)
MATCH(title, content)
AGAINST('A' IN BOOLEAN MODE)
-- でもtitleの方を重要視したい!
-- ↓Mroongaの拡張
AGAINST('*W1:10,2:1 A' IN BOOLEAN MODE)
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 30

不便解消:Mroonga
全文検索+ORDER LIMIT高速化
SELECT * FROM tweets
WHERE
MATCH(content)
AGAINST('...' IN BOOLEAN MODE)
ORDER BY timestamp DESC
LIMIT 10;
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 31

ORDER LIMIT高速化
なぜ速いか
Groongaでソートし、LIMIT件だけ
MySQLに返しているから
MySQLよりGroongaでやった方が速い
(ヒント:カラムストア)
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 32

さらにORDER LIMIT高速化
SELECT * FROM tweets
WHERE
MATCH(content)
AGAINST('...' IN BOOLEAN MODE) AND
timestamp >= '2016-02-01'
-- ↑今月の分だけ対象にしたい
ORDER BY timestamp DESC
LIMIT 10;
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 33

さらにORDER LIMIT高速化
なぜ速いか
Groongaで絞り込んでソートし、
LIMIT件だけMySQLに返しているから
MySQLよりGroongaでやった方が速い
(ヒント:カラムストア)
場合によっては10倍以上高速化
http://tech.gmo-media.jp/post/69542751128/
mroonga-311-new-optimization
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 34

PGroonga
Groongaのフル機能は諦める
速度など譲れない部分はがんばる
その分、使いやすさを重視
使いやすさ1=
MySQL・PostgreSQLとなじんでいる
使いやすさ2=
MySQL・PostgreSQLの不便を解消
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 35

なじみ度:PGroonga
インデックス作成:
PostgreSQLと同じ
CREATE INDEX name ON texts
USING pgroonga (content);
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 36

なじみ度:PGroonga
全文検索:
PostgreSQLのtextsearchとほぼ同
じ
SELECT * FROM ...
WHERE
column @@ 'キーワード';
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 37

textsearchとの違い
構文
-- textsearch
-- プログラムのよう
'(A & B) | C'
-- PGroonga(不便解消)
-- Web検索エンジンのよう
'(A B) OR C'
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 38

不便解消:PGroonga
Windows用バイナリーあり
商用ログ管理製品
「VVAULT AUDIT」が採用
http://vvault.jp/product/vvault-audit/
アクセスログに対して
ユーザー名・パスを全文検索
決め手:高速・省スペース
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 39

不便解消:PGroonga
JSONデータを全文検索
CREATE TABLE logs (record jsonb);
CREATE INDEX i ON logs
USING pgroonga (record);
-- ログのどこかに「error」があればマッチ
SELECT * FROM logs
WHERE record @@ 'string @ "error"';
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 40

JSON全文検索例
以下は全部マッチ
{"message": "Error!"}
{"tags": ["web", "error"]}
{"syslog": {"message": "error!"}}
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 41

使いたい!?
HerokuのPostgreSQLで
PGroongaを使えるなら
Herokuを使いたい!
#herokujp
↑と思うならtweet!
(Herokuの人が観測します。)
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 42

まとめ1
Groonga(ぐるんが)
国産の高速全文検索エンジン
Mroonga(むるんが)
MySQLからGroongaを使える!
PGroonga(ぴーじーるんが)
PostgreSQLからGroongaを使える!
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 43

まとめ2
実装方針
Groongaをできるだけ活かす
(例:速度)
MySQL/PostgreSQLっぽく使える
MySQL/PostgreSQLをより便利に
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Page: 44

次回予告
トランザクションは?
クラッシュしたら?
レプリケーションは?
もっと速くならないの?
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索
Powered by Rabbit 2.1.9

Other slides

Mroonga!
2015-10-30