• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
pg_bigm(ピージーバイグラム)を用いた全文検索のしくみ
 

pg_bigm(ピージーバイグラム)を用いた全文検索のしくみ

on

  • 4,013 views

 

Statistics

Views

Total Views
4,013
Views on SlideShare
3,123
Embed Views
890

Actions

Likes
4
Downloads
0
Comments
0

5 Embeds 890

http://oss.nttdata.co.jp 689
http://opensol.jp.nttdata.com 143
http://210.144.6.128 47
https://twitter.com 9
http://translate.googleusercontent.com 2

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    pg_bigm(ピージーバイグラム)を用いた全文検索のしくみ pg_bigm(ピージーバイグラム)を用いた全文検索のしくみ Presentation Transcript

    • Copyright © 2013 NTT DATA Corporation2013年6月8日株式会社NTTデータ 基盤システム事業本部澤田 雅彦pg_bigm(ピージーバイグラム)を用いた全文検索のしくみ(前編)第26回しくみ勉強会
    • 2Copyright © 2013NTT DATA CorporationINDEX1. 全文検索とは?2. pg_bigmとは?3. pg_bigmの全文検索のしくみ4. pg_bigmの性能測定(前編)5. まとめ
    • Copyright © 2013 NTT DATA Corporation 3全文検索とは?
    • 4Copyright © 2013 NTT DATA Corporation全文検索ってなに?全文検索ってなに? 複数のテキストからキーワードを含むテキストを見つけ出す事(英語辞書から特定の単語を探す、Web検索、など)東京都・・・・・・・・・・・・・・・・・・・・・図書館・・・・・・・・・・・・・・・・・・・・・・・・・・オープンソース・・・・・・・・・・・・・・・・・・・・・・・・本。・学校・・・・・・・・・東京都で・・・・・・・・・・・・・・・・・・・・・データベース・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・東京都・・・・・・・・・・・・・・・・・・・・・図書館・・・・・・・・・・・・・・・・・・・・・・・・・・オープンソース・・・・・・・・・・・・・・・・・・・・・・・・本。・学校・・・・・・・・・全文検索キーワード「オープンソース」
    • 5Copyright © 2013 NTT DATA CorporationDBの全文検索ってなに?SQL発行DB:: テキスト型の列を持つテーブルから、キーワードを含むレコードを検索すること 全文検索では検索対象のデータが多い 全文検索用のインデックスを作成することで高速にできる インデックスのキーの作り方として。。。N-gram方式、形態素解析方式があるキーワード:「オープンソース」
    • 6Copyright © 2013 NTT DATA Corporation形態素解析とN-gram形態素解析 N-gram分割方法 単語単位で分割 文字単位で分割例)’今日は全文検索の日’ではどうなる?キーワード 「今日」,「全文検索」,「日」(2-gramの場合)「今日」,「日は」,「は全」,「全文」,「文検」、「検索」、「索の」…<一般的な特徴>インデックスサイズ 小さい 大きい表記の揺れ 類義語を定義しやすい例)「今日」⇔「本日」を対応させる表記の揺れに弱い検索結果 単語の分割方法に依存する例)「全文」と「検索」は分ける?分けない?LIKEに近い結果を得ることができるどういう時に有効? 整った文章(論文等)を扱う時 記号や造語を検索する時
    • 7Copyright © 2013 NTT DATA CorporationPostgreSQLでN-gramの全文検索をするには(今まで)PostgreSQLに付属しているpg_trgmを使用していた。しかしpg_trgmには以下の弱みがある。。→pg_bigmでは上記の2つの問題を解決しています! 1、2文字検索でインデックスを有効に使えない(SeqScanより遅くなる)→ 例えば「車」、「日本」などの検索キーワードは日本語検索時には十分考えられる 日本語対応をさせるためには、ソースコードの変更が必要→ trgm.hの一部を変更しないといけない
    • Copyright © 2013 NTT DATA Corporation 82. pg_bigmとは?
    • 9Copyright © 2013 NTT DATA Corporationpg_bigmとは pg_bigmとは→2-gramの全文検索モジュール対応バージョン PostgreSQL9.1以降ライセンス PostgreSQL License開発主体 NTTデータ公開日 2013年4月入手元 http://pgbigm.sourceforge.jp/
    • 10Copyright © 2013 NTT DATA Corporationpg_bigmとその他の仲間たちpg_bigm pg_trgm textsearch_groonga作成方法 2-gram 3-gram N-gram対応バージョン 9.1以降 9.1以降 9.1まで開発主体 NTTデータPostgreSQLコミュニティ板垣氏(個人)日本語対応 ○ △ ○依存モジュール なし なしあり(groonga)レプリケーション・リカバリ対応○ ○ ×
    • 11Copyright © 2013 NTT DATA Corporationpg_bigmの特徴 2-gramの全文検索モジュール PostgreSQL内部にインデックスを持つ(GINインデックス) PostgreSQLのレプリケーション、リカバリ対応 1,2文字検索対応 日本語検索対応 データベースエンコーディングはUTF8、ロケールはCにのみ対応
    • Copyright © 2013 NTT DATA Corporation 12pg_bigmの使い方
    • 13Copyright © 2013 NTT DATA Corporationインストール インストールはいつも通り$ tar zxf pg_bigm-20130405.tar.gz$ cd pg_bigm-20130405$ make USE_PGXS=1 PG_CONFIG=$PGHOME/bin/pg_config$ su# make USE_PGXS=1 PG_CONFIG=$PGHOME/bin/pg_config install
    • 14Copyright © 2013 NTT DATA Corporationpg_bigmの登録 pg_bigmの登録$ initdb –D $PGDATA --locale=C --encoding=UTF8$ vi $PGDATA/postgresql.confshared_preload_libraries = pg_bigmcustom_variable_classes = ‘pg_bigm‘ (custom_variable_classesは9.2以降では廃止)$ pg_ctl start -D PGDATA$ psql -d <データベース名>=# CREATE EXTENSION pg_bigm;=# ¥dxList of installed extensionsName | Version | Schema | Description--------+------+------+--------------------------------pg_bigm | 1.0 | public | text index searching based on bigrams
    • 15Copyright © 2013 NTT DATA Corporationインデックス作成まで テーブル定義作成=# CREATE TABLE pg_tools (tool text, description text); データ投入=# INSERT INTO pg_tools VALUES (pg_hint_plan, HINT句を使えるようにするツール);=# INSERT INTO pg_tools VALUES (pg_dbms_stats, 統計情報を固定化するツール);=# INSERT INTO pg_tools VALUES (pg_bigm, 2-gramの全文検索を使えるようにするツール);=# INSERT INTO pg_tools VALUES (pg_trgm, 3-gramの全文検索を使えるようにするツール); インデックス作成=# CREATE INDEX pg_tools_idx ON hoge USING gin (description gin_bigm_ops); マルチカラムインデックス作成=# CREATE INDEX pg_tools_multi_idx ON pg_tools USING gin( tool gin_bigm_ops,description gin_bigm_ops);GINインデックス(転置インデックス)の詳細は後程説明します
    • 16Copyright © 2013 NTT DATA Corporation 実行例=# SELECT * FROM pg_tools WHERE description LIKE ‘%全文%’;tool | description------+------------------------------pg_bigm | 2-gramの全文検索を使えるようにするツールpg_trgm | 3-gramの全文検索を使えるようにするツール(2 rows)簡単な実行例=# EXPLAIN ANALYZE SELECT * FROM pg_tools WHERE description LIKE %全文%;QUERY PLAN------------------------------------------------------------------Bitmap Heap Scan on pg_tools (cost=8.00..12.01 rows=1 width=64) (actual time=0.033..0.034 rows=2loops=1)Recheck Cond: (description ~~ %全文%::text)-> Bitmap Index Scan on pg_tool_idx (cost=0.00..8.00 rows=1 width=0) (actual time=0.025..0.025rows=2 loops=1)Index Cond: (description ~~ %全文%::text)Total runtime: 0.094 ms(5 rows)
    • Copyright © 2013 NTT DATA Corporation 17pg_bigmの全文検索のしくみ
    • 18Copyright © 2013 NTT DATA CorporationGINインデックスとは GINインデックス(Generalized Inverted Index)とは?(Wikipediaより)全文検索を行う対象からなる文章分から位置情報を格納するための索引構造。転置索引、逆引き索引などとも呼ばれる(PostgreSQLマニュアルより)GINインデックスは(キー、投稿されたリスト)の組み合わせの集合を格納します。ここで"投稿されたリスト"はキーに合う行IDの集合です。→「キー」と、「そのキーが出現するTID」の組み合わせを格納するインデックス
    • 19Copyright © 2013 NTT DATA CorporationGINインデックスとは検索キーワード:「accelerometers compensation」「accelerometers」5, 10, 25 ,28, 30, 36, 58, 59, 61,73, 74「compensation」30, 68「accelerometers compensation 」→30ページにある
    • 20Copyright © 2013 NTT DATA Corporation pg_trgmとpg_bigmのインデックス登録時の挙動の説明をしていきます pg_trgmではキーをINT値で持つ pg_bigmではキーを文字列で持つインデックス登録時の挙動キー TID△△P 100△PO 100POS 100CRC1 100CRC2 100CRC3 100①3文字分割「△△P」、「△PO」、「POS」、「OSぐ」、「Sぐれ」、「ぐれ△」②ハッシュ変換+ソート「△△P」、「△PO」、「POS」、「CRC1」、「CRC2」、「CRC3」①2文字分割「△P」、「PO」、「OS」、「Sぐ」、「ぐれ」、「れ△」②ソート「△P」、「PO」、「OS」、「Sぐ」、「ぐれ」、「れ△」pg_bigm キー TID△P 100PO 100OS 100Sぐ 100ぐれ 100れ△ 100TID データ100 POSぐれpg_trgmキーワード‘POSぐれ’INSERT3Byte以上のtrgmは3Byteにハッシュ変換されますINT値で格納されるテキスト型で格納される
    • 21Copyright © 2013 NTT DATA Corporationインデックス検索時の挙動①2文字分割「OS」「Sぐ」「ぐれ」 キーワード‘%OSぐれ%’からTID100のデータが検索されるまでの挙動を解説します②インデックススキャンTID データ100 POSぐれ200 POSぐる300 ぽSぐれキー TID△P 100, 200△ぽ 300OS 100, 200PO 100, 200Sぐ 100, 200, 300る△ 200れ△ 100, 300ぐれ 100, 300: :③TID候補決定→TID 100④Recheck検索キーワード‘%OSぐれ%’pg_bigmの場合
    • 22Copyright © 2013 NTT DATA CorporationRecheck処理の必要性キー TID東京 1京都 1京と 1: :検索ワード:‘%東京都%’「東京」 : TID1「京都」 : TID1TABLEINDEX間違った結果を取ってきてしまうINDEXを検索TID決定Recheck処理で再検査!例えばこんな時。。1 東京と京都: :
    • 23Copyright © 2013 NTT DATA CorporationRecheck処理の必要性実際に見てみる。postgres=# EXPLAIN ANALYZE SELECT * FROM hoge WHERE col1 LIKE ‘%東京都%;QUERY PLAN---------------------------------------------------------Bitmap Heap Scan on hoge (cost=16.00..20.01 rows=1 width=32) (actualtime=0.019..0.019 rows=0loops=1)Recheck Cond: (col1 ~~ ‘%東京都%::text)Rows Removed by Index Recheck: 1-> Bitmap Index Scan on hoge_idx (cost=0.00..16.00 rows=1 width=0) (actualtime=0.011..0.011 rows=1loops=1)Index Cond: (col1 ~~ ‘%東京都%::text)Total runtime: 0.046 ms(5 rows)Bitmap Index Scanでは1行検出しているが、Rechek処理により間違った結果を排除していることがわかる。
    • 24Copyright © 2013 NTT DATA Corporation部分一致とは?①2文字分割「本」②インデックススキャンキー TID: :末尾 100, 200本日 200, 300本屋 500本当 400札束 200: :③TID候補決定 ④Recheckキーワード‘%本%’ 2文字分割後、1文字のキーワードが生成された場合、部分一致を行う関数が実行される(例)検索キーワードが’%東%’の場合など 部分一致では1文字の検索キーワードと各キーの先頭を比較して、一致、不一致を判断する pg_bigmでは部分一致関数を実装しているため、2文字”以下”の検索ができる
    • Copyright © 2013 NTT DATA Corporation 25pg_bigmの性能
    • 26Copyright © 2013 NTT DATA Corporation性能測定の概要① pg_bigmとpg_trgmを比較 pg_bigm→2013年4月に新しく公開されたモジュール。 pg_trgm→おなじみのPostgreSQL付属のモジュール。日本語対応を有効にして参加。 以下の項目の順番に検証を実施1. インデックスサイズ→ 1、2を前編で実施2. インデックス作成時間3. 検索時間→ 3、4を後編で実施4. インデックス更新時間
    • 27Copyright © 2013 NTT DATA Corporation性能測定の概要② テストデータ日本語と英語が混在したテキスト日本語 : 青空文庫より英語 : Project Gutenbergより (単語の途中で区切られないようにしてある) テーブル定義CREATE TABLE hoge (col1 text); テーブル行数約85万行 (日本語60万行、英語25万行) 一行あたりのデータサイズ約600Byte(日本語:200文字/行、英語:600文字/行) テーブルサイズ約612MB
    • 28Copyright © 2013 NTT DATA Corporationマシンスペック・ソフトウェア関連情報項目 詳細OS Red Hat Enterprise Linux 6.3(64bit)DBMS PostgreSQL 9.2.4項目 詳細メーカー DELLモデル PowerEdge C8220XCPU Xeon(R) E5-2660 2.20GHz ×2メモリ 24GBディスク HDD1本(RAID構成なし)回転数:7200rpm、容量:1TB
    • 29Copyright © 2013 NTT DATA Corporationインデックスサイズと作成時間の比較 概要 データCOPY→インデックス作成の流れで、インデックスのサイズと作成にかかる時間を計測 全てGINインデックスを使用 それぞれ10回計測を行い、その平均値を結果とする対象 インデックス作成クエリpg_bigm CREATE INDEX hoge_idx ON hoge USING gin (col1 gin_bigm_ops);pg_trgm CREATE INDEX hoge_idx ON hoge USING gin (col1 gin_trgm_ops);
    • 30Copyright © 2013 NTT DATA Corporationインデックスサイズの比較 今回の測定条件ではpg_bigmの方がインデックスサイズが小さいという結果になった 2文字分割の方が分割後のデータが重複する確率が高い→重複したデータは削除される(参考) 一つのインデックスキーの大きさの比較 pg_bigm : 英語は「3byte」 ←(データ2byte+TEXT型のヘッダ1Byte)日本語は「(2文字のバイト数の合計)+(TEXT型のヘッダ1Byte)」 pg_trgm : 4byte(INT値で格納するため。日本語はハッシュ変換される)(例) 「this」→インデックスキーが5つできる(pg_bigm、pg_trgm共通)pg_bigm : 3Byte×5個 = 15Byte、 pg_trgm : 4Byte×5個 = 20Byte対象 テーブルサイズ インデックスサイズpg_bigm612MB1523MBpg_trgm 2154MB
    • 31Copyright © 2013 NTT DATA Corporationインデックス作成時間の比較対象 COPY CREATE INDEX Totalpg_bigm15秒589秒 604秒pg_trgm 785秒 800秒 今回の測定条件ではpg_bigmの方がインデックス作成時間が短いという結果になった pg_trgmの方が書き込むサイズが大きいため (インデックスサイズ結果参照) pg_trgmはハッシュ変換のオーバーヘッドがある
    • Copyright © 2013 NTT DATA Corporation 32まとめ
    • 33Copyright © 2013 NTT DATA Corporationまとめ まとめ pg_bigmでは日本語に対応している 1、2文字検索に対応している (今回の測定条件では)pg_bigmの方がpg_trgmと比べてインデックスサイズが小さく、作成時間も短かった 日本語2文字以下の検索をする要件 → pg_bigm一択か? 次回予定 pg_bigmの性能測定(後半) 様々な長さの検索キーワード(英語、日本語)での検索性能 インデックスの更新性能 pg_bigm独自機能やpg_bigmが提供しているパラメータの紹介
    • Copyright © 2011 NTT DATA CorporationCopyright © 2013 NTT DATA Corporation
    • 35Copyright © 2013 NTT DATA Corporation(参考)ワイルドカードの有無による検索の挙動の違いキー TID△A 1, 2△X 3AB 1, 2, 3BC 1, 2, 3C△ 1, 3CD 2D△ 2XA 1TID データ1 ABC2 ABCD3 XABC検索キーワード キー 決定タプル完全一致 ABC△AABC△1前方一致 %ABCABBCC△1, 2中間一致 %ABC%ABBC1, 2, 3後方一致 ABC%△AABBC1
    • 36Copyright © 2013 NTT DATA Corporation(参考)英語だけのテーブル、日本語だけのテーブルでのインデックスサイズ対象 テーブルサイズ サイズ 差英語だけpg_bigm138MB401MB133MB英語だけpg_trgm 534MB日本語だけpg_bigm500MB1119MB497MB日本語だけpg_trgm 1616MB
    • 37Copyright © 2013 NTT DATA Corporation(参考) 部分一致までの挙動詳細①‘%a%bcd%’②、③pmatchtruefalsefalsebigmabccd対応④1.問い合わせキーとインデックスキーの一文字目のバイト長を比較。一致→2へ。不一致→「1」を返す2.文字を比較。一致→「0」を返す。不一致「1」を返す。‘a’と’a)’ → 「0」を返す‘a’と’a/’ → 「0」を返す‘a’と’aa’ → 「0」を返す‘a’と’ax → 「0」を返す‘a’と’b△’ → 「1」を返すginインデックスa) a/ aa ax b△ ・・・gin_extract_query_bigm()gin_bigm_compare_partial()