29
Copyright © 2016 NTT DATA Corporation 2016年2月9日 株式会社NTTデータ 澤田雅彦 PostgreSQLでpg_bigmを使って日本語全文検索 ~pg_bigmで全文検索するときに知っておくべき8のこと~ @MySQLとPostgreSQLの日本語全文検索勉強会

PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

Embed Size (px)

Citation preview

Page 1: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

Copyright © 2016 NTT DATA Corporation

2016年2月9日株式会社NTTデータ 澤田雅彦

PostgreSQLでpg_bigmを使って日本語全文検索

~pg_bigmで全文検索するときに知っておくべき8のこと~

@MySQLとPostgreSQLの日本語全文検索勉強会

Page 2: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

2Copyright © 2016 NTT DATA Corporation

PostgreSQL 9.5 リリース!

1/7にリリースされました!

Page 3: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

3Copyright © 2016 NTT DATA Corporation

PostgreSQL 開発者@ NTT データ

社内 PostgreSQL 営業・技術支援

PostgreSQL のコア機能を開発

レプリケーション運用性向上

REINDEX SCHEMA / VERBOSE

pg_bigm(全文検索モジュール)

コア機能へのパッチレビューア

澤田 雅彦 @sawada_masahiko

Page 4: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

4Copyright © 2016 NTT DATA Corporation

「PostgreSQL 全文検索 日本語」で検索

pg_bigm

textsearch_ja

pg_trgm

pgroonga

Page 5: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

5Copyright © 2016 NTT DATA Corporation

PostgreSQLで使える日本語全文検索モジュールはいろいろ

• pgroonga

• pg_bigm

• pg_trgm

• unigram

• textsearch_ja

• textsearch_groonga

• textsearch_senna

など

Page 6: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

6Copyright © 2016 NTT DATA Corporation

形態素解析 N-gram

分類すると

• textsearch_ja

• pgroonga

• textsearch_groonga

• pg_bigm

• pg_trgm

• unigram

• textsearch_senna

Page 7: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

Copyright © 2016 NTT DATA Corporation 7

pg_bigmで全文検索するときに知っておくべき8のこと

Page 8: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

8Copyright © 2016 NTT DATA Corporation

1.

全文検索インデックスが

必要ない検索と

必要ある検索

Page 9: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

9Copyright © 2016 NTT DATA Corporation

全文検索インデックスが必要ない/ある検索

全文検索インデックスが必要ない検索

• テーブル件数が少ない → シーケンシャルスキャンでOK

• 前方一致検索だけ (‘東京%’) → BtreeインデックスでOK

• 後方一致検索だけ (‘%東京’) → Btree(式)インデックスでOK

全文検索インデックスが必要ある検索

• 大きいテーブルで中間一致検索を使う (‘%東京%’)

• 前方、後方、中間一致検索をする可能性がある

Page 10: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

10Copyright © 2016 NTT DATA Corporation

2.

なぜpg_bigmを開発したか

Page 11: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

11Copyright © 2016 NTT DATA Corporation

昔、PostgreSQLで全文検索したい時

○ PostgreSQL 8系で日本語全文検索が可能

× 全文検索インデックスは、リカバリ未対応

× クラッシュ後、REINDEXが必要

× 8.3以降のVACUUMに未対応

× PostgreSQL9系には未対応

Page 12: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

12Copyright © 2016 NTT DATA Corporation

PostgreSQL本体でもN-gram全文検索の利用が可能に

○ PostgreSQL付属モジュール

○ インデックスはPostgreSQLが管理

× 日本語(マルチバイト文字)に未対応

× 1,2文字検索が低速

Page 13: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

13Copyright © 2016 NTT DATA Corporation

N-gramで日本語対応

pg_bigmはpg_trgmを日本語検索に強化・最適化したモジュール

pg_bigm(バイグラム)

pg_trgm(トライグラム)

インデックスの作成方法

2-gram 3-gram

日本語対応 ○ ×

1,2文字検索 高速 低速

Page 14: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

14Copyright © 2016 NTT DATA Corporation

3.

1,2文字検索に対応

Page 15: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

15Copyright © 2016 NTT DATA Corporation

1,2文字の検索に対応

• pg_trgmでは検索キーワードが3文字以上でないと、インデックスを使った高速な検索ができない。

• pg_bigmでは1,2文字(本、学校など)の検索でもインデックスを使用した高速な検索が可能。

検索例 pg_bigm pg_trgm

col LIKE ‘%駅%’ 高速 低速

col LIKE ‘%東京%’ 高速 低速

col LIKE ‘%東京駅%’ 高速 高速

Page 16: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

16Copyright © 2016 NTT DATA Corporation

4.

性能情報

Page 17: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

17Copyright © 2016 NTT DATA Corporation

検索キーワード 取得件数 pg_bigm pg_trgm SeqScan

町 17万件 0.4 秒 504 秒

15 秒

東京 16万件 0.3 秒 407 秒

東京都 4万件 0.2 秒 0.2 秒

東京と京都 150件 0.004 秒 0.001 秒

昭和四十四年度以降 150件 0.08 秒 0.02 秒

性能情報

日本語データを全文検索(サイズ:6GB、データ件数:1300万件)

Page 18: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

18Copyright © 2016 NTT DATA Corporation

5.

pg_bigmを使うために

必要な4ステップ

Page 19: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

19Copyright © 2016 NTT DATA Corporation

pg_bigmを使うために必要な4ステップ

1. RPMインストール

• PostgreSQLのバージョンに合ったRPMをダウンロードし、インストール

• https://osdn.jp/projects/pgbigm/releases/p13634

2. 設定ファイルに追記

• postgresql.confに「shared_preload_libraries = ‘pg_bigm’」を追記

3. pg_bigmをPostgreSQLに登録

• CREATE EXTENSION pg_bigm;

4. 全文検索インデックスを作成

• CREATE INDEX hoge_idx ON hoge USING gin (col gin_bigm_ops);

Page 20: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

20Copyright © 2016 NTT DATA Corporation

6.

PostgreSQLの

GINインデックスを利用

Page 21: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

21Copyright © 2016 NTT DATA Corporation

PostgreSQLのGINインデックスを利用

• 全文検索インデックス自体はPostgreSQLが管理。

• pg_bigmはGINインデックスへのアクセス方法のみを提供

• リカバリ、PITR、レプリケーションはPostgreSQLに任せることが可能。

WAL

pg_bigm

GINインデックス

テーブル

サーバプロセス

WALを書く

アクセス

PostgreSQL内部

アクセス

Page 22: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

22Copyright © 2016 NTT DATA Corporation

7.

PostgreSQL 9.4以降

との組み合わせがおすすめ

Page 23: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

23Copyright © 2016 NTT DATA Corporation

PostgreSQL9.4以降がおすすめ

PostgreSQL9.4でGINインデックスのサイズ、検索性能が改善されました。

検索キーワード

PG9.3 +

pg_bigm

PG9.4+

pg_bigm

東京 0.8 秒 0.3 秒

東京都 0.5 秒 0.2 秒

東京と京都 0.03秒 0.004 秒

昭和四十四年度以降

0.3秒 0.08 秒

6.5 GB

10 GB

3.7 GB

■GINインデックスの圧縮 ■検索性能の向上

Page 24: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

24Copyright © 2016 NTT DATA Corporation

8.

“文字の種類を意識しない”

全文検索が可能

Page 25: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

25Copyright © 2016 NTT DATA Corporation

“文字の種類を意識しない”全文検索が可能

=# SELECT * FROM hoge WHERE pgs2norm(col) LIKE likequery(pgs2norm('%ポスグレ%‘));

col

--------------------------

半角文字でポスグレ

全角文字でポスグレ

半角、全角を混ぜてポスグレ

(3 rows)

=# SELECT * FROM hoge WHERE pgs2norm(col) LIKE likequery(pgs2norm('%1番目%‘));

col

--------

1番目

1番目

①番目

半角文字で全角文字を、全角文字で半角文字を検索。

Page 26: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

26Copyright © 2016 NTT DATA Corporation

「ludia_funcs」を使用

• 正規化関数を使用した関数インデックスを作成

• GINインデックスには正規化された文字情報が格納される

• 依然、GINインデックスはPostgreSQLが管理

pg_bigm

「1番」「番目」

ludia_funcs「①番目」 「1番目」

入力データ「①番目」

正規化関数

=# CREATE INDEX … USING gin (pg2norm(col) gin_bigm_ops);

GINインデックス

=# SELECT * FROM hoge WHERE pgs2norm(col) LIKE likequery(pgs2norm('%ポスグレ%’));

Page 27: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

27Copyright © 2016 NTT DATA Corporation

最後に

1. 全文検索インデックスが必要ない検索と必要ある検索

2. なぜpg_bigmを開発したか

3. 1,2文字検索に対応

4. 性能情報

5. pg_bigmを使うまでに必要な4ステップ

6. PostgreSQLのGINインデックスを利用

7. PostgreSQL9.4以降との組み合わせがおすすめ

8. “文字の種類を意識しない”全文検索が可能

Page 28: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

Copyright © 2011 NTT DATA Corporation

Copyright © 2016 NTT DATA Corporation

Page 29: PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料)

29Copyright © 2016 NTT DATA Corporation

(参考)N-gramと形態素解析

N-gram

• 文章を文字単位で分割 (‘夜景が綺麗’ → ‘夜景’, ‘景が’, ‘が綺’, ‘綺麗’)

• 漏れがなく全文検索することが可能 (造語、新出語も対応)

• 採用モジュール : pg_bigm, pg_trgm, pgroonga, unigram, textsearch_senna

形態素解析

• 文章を単語単位で分割 (‘夜景が綺麗’ → ‘夜景’, ‘綺麗’)

• 検索ノイズの少ない全文検索することが可能 (京都で「東京都庁」がヒットしない)

• 採用モジュール : pgroonga, textsearch_ja, textsearch_groonga

pg_bigmは2-gramを採用