KEMBAR78
PostgreSQLでpg_bigmを使って日本語全文検索 (MySQLとPostgreSQLの日本語全文検索勉強会 発表資料) | PDF
Copyright © 2016 NTT DATA Corporation
2016年2月9日
株式会社NTTデータ 澤田雅彦
PostgreSQLでpg_bigmを使って日本語全文検索
~pg_bigmで全文検索するときに知っておくべき8のこと~
@MySQLとPostgreSQLの日本語全文検索勉強会
2Copyright © 2016 NTT DATA Corporation
PostgreSQL 9.5 リリース!
1/7にリリース
されました!
3Copyright © 2016 NTT DATA Corporation
PostgreSQL 開発者@ NTT データ
社内 PostgreSQL 営業・技術支援
PostgreSQL のコア機能を開発
レプリケーション運用性向上
REINDEX SCHEMA / VERBOSE
pg_bigm(全文検索モジュール)
コア機能へのパッチレビューア
澤田 雅彦 @sawada_masahiko
4Copyright © 2016 NTT DATA Corporation
「PostgreSQL 全文検索 日本語」で検索
pg_bigm
textsearch_ja
pg_trgm
pgroonga
5Copyright © 2016 NTT DATA Corporation
PostgreSQLで使える日本語全文検索モジュールはいろいろ
• pgroonga
• pg_bigm
• pg_trgm
• unigram
• textsearch_ja
• textsearch_groonga
• textsearch_senna
など
6Copyright © 2016 NTT DATA Corporation
形態素解析 N-gram
分類すると
• textsearch_ja
• pgroonga
• textsearch_
groonga
• pg_bigm
• pg_trgm
• unigram
• textsearch_senna
Copyright © 2016 NTT DATA Corporation 7
pg_bigmで全文検索するときに知っておくべき8のこと
8Copyright © 2016 NTT DATA Corporation
1.
全文検索インデックスが
必要ない検索と
必要ある検索
9Copyright © 2016 NTT DATA Corporation
全文検索インデックスが必要ない/ある検索
全文検索インデックスが必要ない検索
• テーブル件数が少ない → シーケンシャルスキャンでOK
• 前方一致検索だけ (‘東京%’) → BtreeインデックスでOK
• 後方一致検索だけ (‘%東京’) → Btree(式)インデックスでOK
全文検索インデックスが必要ある検索
• 大きいテーブルで中間一致検索を使う (‘%東京%’)
• 前方、後方、中間一致検索をする可能性がある
10Copyright © 2016 NTT DATA Corporation
2.
なぜpg_bigmを開発したか
11Copyright © 2016 NTT DATA Corporation
昔、PostgreSQLで全文検索したい時
○ PostgreSQL 8系で日本語全文検索が可能
× 全文検索インデックスは、リカバリ未対応
× クラッシュ後、REINDEXが必要
× 8.3以降のVACUUMに未対応
× PostgreSQL9系には未対応
12Copyright © 2016 NTT DATA Corporation
PostgreSQL本体でもN-gram全文検索の利用が可能に
○ PostgreSQL付属モジュール
○ インデックスはPostgreSQLが管理
× 日本語(マルチバイト文字)に未対応
× 1,2文字検索が低速
13Copyright © 2016 NTT DATA Corporation
N-gramで日本語対応
pg_bigmはpg_trgmを日本語検索に強化・最適化したモジュール
pg_bigm
(バイグラム)
pg_trgm
(トライグラム)
インデックスの
作成方法
2-gram 3-gram
日本語対応 ○ ×
1,2文字検索 高速 低速
14Copyright © 2016 NTT DATA Corporation
3.
1,2文字検索に対応
15Copyright © 2016 NTT DATA Corporation
1,2文字の検索に対応
• pg_trgmでは検索キーワードが3文字以上でないと、インデックスを使った高速な検索ができない。
• pg_bigmでは1,2文字(本、学校など)の検索でもインデックスを使用した高速な検索が可能。
検索例 pg_bigm pg_trgm
col LIKE ‘%駅%’ 高速 低速
col LIKE ‘%東京%’ 高速 低速
col LIKE ‘%東京駅%’ 高速 高速
16Copyright © 2016 NTT DATA Corporation
4.
性能情報
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万件)
18Copyright © 2016 NTT DATA Corporation
5.
pg_bigmを使うために
必要な4ステップ
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);
20Copyright © 2016 NTT DATA Corporation
6.
PostgreSQLの
GINインデックスを利用
21Copyright © 2016 NTT DATA Corporation
PostgreSQLのGINインデックスを利用
• 全文検索インデックス自体はPostgreSQLが管理。
• pg_bigmはGINインデックスへのアクセス方法のみを提供
• リカバリ、PITR、レプリケーションはPostgreSQLに任せることが可能。
WAL
pg_bigm
GIN
インデックス
テーブル
サーバ
プロセス
WALを書く
アクセス
PostgreSQL内部
アクセス
22Copyright © 2016 NTT DATA Corporation
7.
PostgreSQL 9.4以降
との組み合わせがおすすめ
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インデックスの圧縮 ■検索性能の向上
24Copyright © 2016 NTT DATA Corporation
8.
“文字の種類を意識しない”
全文検索が可能
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番目
①番目
半角文字で全角文字を、全角文字で半角文字を検索。
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('%ポスグレ%’));
27Copyright © 2016 NTT DATA Corporation
最後に
1. 全文検索インデックスが必要ない検索と必要ある検索
2. なぜpg_bigmを開発したか
3. 1,2文字検索に対応
4. 性能情報
5. pg_bigmを使うまでに必要な4ステップ
6. PostgreSQLのGINインデックスを利用
7. PostgreSQL9.4以降との組み合わせがおすすめ
8. “文字の種類を意識しない”全文検索が可能
Copyright © 2011 NTT DATA Corporation
Copyright © 2016 NTT DATA Corporation
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を採用

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

  • 1.
    Copyright © 2016NTT DATA Corporation 2016年2月9日 株式会社NTTデータ 澤田雅彦 PostgreSQLでpg_bigmを使って日本語全文検索 ~pg_bigmで全文検索するときに知っておくべき8のこと~ @MySQLとPostgreSQLの日本語全文検索勉強会
  • 2.
    2Copyright © 2016NTT DATA Corporation PostgreSQL 9.5 リリース! 1/7にリリース されました!
  • 3.
    3Copyright © 2016NTT DATA Corporation PostgreSQL 開発者@ NTT データ 社内 PostgreSQL 営業・技術支援 PostgreSQL のコア機能を開発 レプリケーション運用性向上 REINDEX SCHEMA / VERBOSE pg_bigm(全文検索モジュール) コア機能へのパッチレビューア 澤田 雅彦 @sawada_masahiko
  • 4.
    4Copyright © 2016NTT DATA Corporation 「PostgreSQL 全文検索 日本語」で検索 pg_bigm textsearch_ja pg_trgm pgroonga
  • 5.
    5Copyright © 2016NTT DATA Corporation PostgreSQLで使える日本語全文検索モジュールはいろいろ • pgroonga • pg_bigm • pg_trgm • unigram • textsearch_ja • textsearch_groonga • textsearch_senna など
  • 6.
    6Copyright © 2016NTT DATA Corporation 形態素解析 N-gram 分類すると • textsearch_ja • pgroonga • textsearch_ groonga • pg_bigm • pg_trgm • unigram • textsearch_senna
  • 7.
    Copyright © 2016NTT DATA Corporation 7 pg_bigmで全文検索するときに知っておくべき8のこと
  • 8.
    8Copyright © 2016NTT DATA Corporation 1. 全文検索インデックスが 必要ない検索と 必要ある検索
  • 9.
    9Copyright © 2016NTT DATA Corporation 全文検索インデックスが必要ない/ある検索 全文検索インデックスが必要ない検索 • テーブル件数が少ない → シーケンシャルスキャンでOK • 前方一致検索だけ (‘東京%’) → BtreeインデックスでOK • 後方一致検索だけ (‘%東京’) → Btree(式)インデックスでOK 全文検索インデックスが必要ある検索 • 大きいテーブルで中間一致検索を使う (‘%東京%’) • 前方、後方、中間一致検索をする可能性がある
  • 10.
    10Copyright © 2016NTT DATA Corporation 2. なぜpg_bigmを開発したか
  • 11.
    11Copyright © 2016NTT DATA Corporation 昔、PostgreSQLで全文検索したい時 ○ PostgreSQL 8系で日本語全文検索が可能 × 全文検索インデックスは、リカバリ未対応 × クラッシュ後、REINDEXが必要 × 8.3以降のVACUUMに未対応 × PostgreSQL9系には未対応
  • 12.
    12Copyright © 2016NTT DATA Corporation PostgreSQL本体でもN-gram全文検索の利用が可能に ○ PostgreSQL付属モジュール ○ インデックスはPostgreSQLが管理 × 日本語(マルチバイト文字)に未対応 × 1,2文字検索が低速
  • 13.
    13Copyright © 2016NTT DATA Corporation N-gramで日本語対応 pg_bigmはpg_trgmを日本語検索に強化・最適化したモジュール pg_bigm (バイグラム) pg_trgm (トライグラム) インデックスの 作成方法 2-gram 3-gram 日本語対応 ○ × 1,2文字検索 高速 低速
  • 14.
    14Copyright © 2016NTT DATA Corporation 3. 1,2文字検索に対応
  • 15.
    15Copyright © 2016NTT DATA Corporation 1,2文字の検索に対応 • pg_trgmでは検索キーワードが3文字以上でないと、インデックスを使った高速な検索ができない。 • pg_bigmでは1,2文字(本、学校など)の検索でもインデックスを使用した高速な検索が可能。 検索例 pg_bigm pg_trgm col LIKE ‘%駅%’ 高速 低速 col LIKE ‘%東京%’ 高速 低速 col LIKE ‘%東京駅%’ 高速 高速
  • 16.
    16Copyright © 2016NTT DATA Corporation 4. 性能情報
  • 17.
    17Copyright © 2016NTT 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万件)
  • 18.
    18Copyright © 2016NTT DATA Corporation 5. pg_bigmを使うために 必要な4ステップ
  • 19.
    19Copyright © 2016NTT 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);
  • 20.
    20Copyright © 2016NTT DATA Corporation 6. PostgreSQLの GINインデックスを利用
  • 21.
    21Copyright © 2016NTT DATA Corporation PostgreSQLのGINインデックスを利用 • 全文検索インデックス自体はPostgreSQLが管理。 • pg_bigmはGINインデックスへのアクセス方法のみを提供 • リカバリ、PITR、レプリケーションはPostgreSQLに任せることが可能。 WAL pg_bigm GIN インデックス テーブル サーバ プロセス WALを書く アクセス PostgreSQL内部 アクセス
  • 22.
    22Copyright © 2016NTT DATA Corporation 7. PostgreSQL 9.4以降 との組み合わせがおすすめ
  • 23.
    23Copyright © 2016NTT 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インデックスの圧縮 ■検索性能の向上
  • 24.
    24Copyright © 2016NTT DATA Corporation 8. “文字の種類を意識しない” 全文検索が可能
  • 25.
    25Copyright © 2016NTT 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番目 ①番目 半角文字で全角文字を、全角文字で半角文字を検索。
  • 26.
    26Copyright © 2016NTT 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('%ポスグレ%’));
  • 27.
    27Copyright © 2016NTT DATA Corporation 最後に 1. 全文検索インデックスが必要ない検索と必要ある検索 2. なぜpg_bigmを開発したか 3. 1,2文字検索に対応 4. 性能情報 5. pg_bigmを使うまでに必要な4ステップ 6. PostgreSQLのGINインデックスを利用 7. PostgreSQL9.4以降との組み合わせがおすすめ 8. “文字の種類を意識しない”全文検索が可能
  • 28.
    Copyright © 2011NTT DATA Corporation Copyright © 2016 NTT DATA Corporation
  • 29.
    29Copyright © 2016NTT DATA Corporation (参考)N-gramと形態素解析 N-gram • 文章を文字単位で分割 (‘夜景が綺麗’ → ‘夜景’, ‘景が’, ‘が綺’, ‘綺麗’) • 漏れがなく全文検索することが可能 (造語、新出語も対応) • 採用モジュール : pg_bigm, pg_trgm, pgroonga, unigram, textsearch_senna 形態素解析 • 文章を単語単位で分割 (‘夜景が綺麗’ → ‘夜景’, ‘綺麗’) • 検索ノイズの少ない全文検索することが可能 (京都で「東京都庁」がヒットし ない) • 採用モジュール : pgroonga, textsearch_ja, textsearch_groonga pg_bigmは 2-gramを採用