Mroonga開発者がn来たぞ!

: author

須藤功平

: institution

クリアコード

: content-source

三木会

: date

2016-11-17

: allotted-time

2h

: theme

.

Mroonga

* 読み方:むるんが

* ストレージエンジン

* (('wait'))MySQL 5.7対応\n
  (('note:もちろん5.5, 5.6も対応'))

* (('wait'))MariaDB 10.2対応\n
  (('note:もちろん5.5, 10.0, 10.1も対応'))
  * 10.0以降はバンドルもされている

特徴

* (('wait'))
  高速日本語全文検索(('note:(全言語OK)'))\n
  (('note:MySQL 5.6以前は日本語未対応'))\n
  (('note:5.7以降は日本語対応しているが遅い'))
* (('wait'))
  カラムストアによる高速処理
* (('wait'))
  全文検索初心者でも使える
* (('wait'))
  全文検索上級者は活用できる

高速日本語全文検索

(1) ベンチマーク
(2) 速さの秘密

ベンチマーク環境

* 対象:Wikipedia日本語版
* レコード数:約185万件
* データサイズ:約7GB
* メモリー4GB・SSD250GB(('note:(ConoHa)'))

補足

* MySQL 5.7を使用
* 他人のベンチマークは参考程度
  * 検討時は実環境でベンチマークを!

(('note:詳細:'))n (('note:github.com/groonga/wikipedia-search/issues/4'))

検索1

(('tag:center')) キーワード:テレビアニメn (('note:(ヒット数:約2万3千件)'))

# RT
delimiter = [|]

InnoDB ngram | 3m2s
InnoDB MeCab | 6m20s
Mroonga:((*1*)) | 0.11s

検索2

(('tag:center')) キーワード:データベースn (('note:(ヒット数:約1万7千件)'))

# RT
delimiter = [|]

InnoDB ngram | 36s
InnoDB MeCab:((*1*)) | 0.03s
Mroonga:((*2*)) | 0.09s

検索3

(('tag:center')) キーワード:PostgreSQL OR MySQLn (('note:(ヒット数:約400件)'))

# RT
delimiter = [|]

InnoDB ngram | N/A(Error)
InnoDB MeCab:((*1*)) | 0.005s
Mroonga:((*2*)) | 0.028s

検索4

(('tag:center')) キーワード:日本n (('note:(ヒット数:約63万件)'))

# RT
delimiter = [|]

InnoDB ngram | 1.3s
InnoDB MeCab | 1.3s
Mroonga:((*1*)) | 0.21s

検索まとめ

* (('wait'))Mroonga:安定して速い
* (('wait'))InnoDB FTS MeCab
  * ハマれば速い
* (('wait'))InnoDB FTS ngram
  * 安定して遅い

速さの秘密

* 最適化された転置索引実装\n
  * (('wait'))2段階のデータ圧縮
  * (('wait'))高速なポスティングリスト探索
  * (('wait'))検索だけでなく更新も速い

(('wait')) (('note:11年以上開発が続いている全文検索エンジンGroongaを使用'))

もっと速さの秘密

* カラムストアを活かした最適化
  * ポイント1:余計なI/Oを減らす
  * ポイント2:I/Oを局所化

カラムストア

# image
# src = images/column-store.svg
# relative_width = 100

必要なカラムのみアクセス

# coderay sql
-- aのみにアクセス
SELECT a
  FROM table
-- cのみにアクセス
 WHERE c = XXX;
-- bにはアクセスしない

減ったI/O

# image
# src = images/not-access-to-needless-columns.svg
# relative_width = 100

行カウント

# coderay sql
-- カラムの値は必要ない
SELECT COUNT(*)
  FROM table
-- cの全文検索インデックスにだけアクセス
 WHERE MATCH(c)
     AGAINST('+keyword' IN BOOLEAN MODE);
-- a, b, cはアクセスしない

減ったI/O

# image
# src = images/count-star.svg
# relative_width = 100

(({ORDER BY LIMIT}))

# coderay sql
SELECT *
  FROM table
 WHERE MATCH(c)
     AGAINST('+keyword' IN BOOLEAN MODE)
-- MySQLではなくMroongaがORDER BY LIMITを処理
-- →Mroongaは10レコードだけMySQLに返す
--   マッチしたレコードすべては返さない
 ORDER BY a LIMIT 10;

(({ORDER BY LIMIT}))の最適化

* (('wait'))Mroongaが検索
  * カラム毎の処理でI/Oを局所化\n
    (('note:(索引非使用時)'))
* (('wait'))Mroongaがソート
  * カラム毎の処理でI/Oを局所化
* (('wait'))Mroongaが(({OFFSET}))/(({LIMIT}))を処理

カラム毎の処理は速い

# image
# src = images/per-column-processing.svg
# relative_width = 100

最適化のまとめ

* 転置索引実装が速い
  * 検索も更新も速い
* カラムストアで速い
  * ポイント:I/O削減・I/O局所化

全文検索初心者でも使える

* (('wait'))インストールが簡単
* (('wait'))MySQLの標準機能のみで使える

インストールが簡単

* (('wait'))APT/Yumリポジトリー
* (('wait'))MariaDBバンドル
* (('wait'))MariaDB込みのWindowsバイナリ

標準機能のみで使える

# coderay sql
-- 作成
CREATE TABLE table (
  -- ...,
  FULLTEXT INDEX (column)
) ENGINE=Mroonga;

標準機能のみで使える

# coderay sql
-- 変換
ALTER TABLE table
  ADD FULLTEXT INDEX (column)
  ENGINE=Mroonga;

標準機能のみで使える

# coderay sql
SELECT * FROM table
  WHERE
    MATCH(column)
    AGAINST('+keyword'
            IN BOOLEAN MODE);

全文検索上級者向け機能

* (('wait'))
  カスタマイズ
  * デフォルト値はいい感じ\n
    →初心者はカスタマイズなしでよい
* (('wait'))
  Groongaの機能をもっと使える\n
  (('note:(高速・高機能)'))

文字正規化ルール変更

# coderay sql
CREATE TABLE table (
  -- ...,
  FULLTEXT INDEX (column)
    --
    -- コメントでパラメーターを指定
    COMMENT='normalizer "NormalizerAuto"'
) ENGINE=Mroonga;

文字正規化ルール変更

# coderay sql
CREATE TABLE table (
  -- ...,
  FULLTEXT INDEX (column)
    -- MariaDBの場合:
    -- カスタムパラメーターを使える
    NORMALIZER='NormalizerAuto'
) ENGINE=Mroonga;

Groongaの検索機能を使う

# coderay sql
SELECT * FROM table
  WHERE
    -- 「*SS」プラグマ使用時は「c1」は無視される
    MATCH(c1)
    -- 「*SS」はGroongaの全検索機能を使うためのプラグマ
    -- 1つのクエリーで複数のインデックスを使用可能
    AGAINST('*SS c1 @ "keyword" && c2 < 100'
            IN BOOLEAN MODE);

今後

* (('wait'))
  最新機能サポート
  * JSONを全文検索\n
    (('note:(JSON型のデータの読み書きは対応済み)'))\n
  * 仮想カラム・生成カラム
  * パーティショニング+全文検索対応
* (('wait'))
  最新版をMariaDBにバンドル

最新版をバンドル

* (('wait'))
  Mroongaは毎月リリース
* (('wait'))
  MariaDB 10.2.1はMroonga ((*5.04*))をバンドル
  * Mroongaの最新版は6.10
  * Mroongaは((*6.03*))からMariaDB 10.2をサポート
  * 現在テスト中→テスト対応後マージ

まとめ1

* (('wait'))
  高速日本語全文検索(('note:(全言語OK)'))
* (('wait'))
  カラムストアによる高速処理
* (('wait'))
  全文検索初心者でも使える
* (('wait'))
  全文検索上級者は活用できる

まとめ2

* (('wait'))
  今後もMroongaは便利になる
* (('wait'))
  MariaDBで最新Mroongaを使える

(('wait')) MySQLで全文検索ならMroonga!