<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div dir="ltr"></div><div dir="ltr"><p style="margin: 0px; font-stretch: normal; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">堀本さま</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 19.1px;"><span style="background-color: rgba(255, 255, 255, 0);"><br></span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">2月下旬に</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">「TokenBigramSplitSymbolAlphaDigit」に関して質問していた江上です。</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 19.1px;"><span style="background-color: rgba(255, 255, 255, 0);"><br></span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">インデックスに上記を適用した際の実行計画を取得してみましたが、5秒程度かかっています。これ以上のチューニング方法はドキュメント上無いように思いますが、他に試す方法があるようであれば、ご教授いただけないかと思っています。</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 19.1px;"><span style="background-color: rgba(255, 255, 255, 0);"><br></span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">今回の利用では、画面上の全項目を部分一致検索対象としていますが、そもそも、数字7桁に対して、部分一致検索する用途があるのか、という話もあるですが。。</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 19.1px;"><span style="background-color: rgba(255, 255, 255, 0);"><br></span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">【テーブル】</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">table:約700万件</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">order_key_value_jsonの中に数十のkey-valueが有り、item004のキーに7桁の数字が入る。</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 19.1px;"><span style="background-color: rgba(255, 255, 255, 0);"><br></span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> 列 型 </span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> sys_no character varying(10)</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> order_key_value_json jsonb</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">インデックス:</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> "table_i1" pgroonga (order_key_value_json) WITH (tokenizer='TokenBigramSplitSymbolAlphaDigit')</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 19.1px;"><span style="background-color: rgba(255, 255, 255, 0);"><br></span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">【実行SQL】</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);">SELECT sys_no FROM table WHERE</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> order_key_value_json operator(pgroonga.@@) 'paths == "item004" && type == "string" && string @ "10000" ';</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> 【QUERY PLAN】</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> Bitmap Heap Scan on public.table (cost=2644.29..344436.42 rows=10577150 width=8) (actual time=5002.838..5005.298 rows=251 loops=1)</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> Output: sys_no</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> Recheck Cond: (table.order_key_value_json OPERATOR(pgroonga.@@) 'paths == "item004" && type == "string" && string @ "10000" '::text)</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> Heap Blocks: exact=179</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> -> Bitmap Index Scan on order_key_value_info_i1 (cost=0.00..0.00 rows=211543 width=0) (actual time=5001.984..5001.984 rows=251 loops=1)</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> Index Cond: (table.order_key_value_json OPERATOR(pgroonga.@@) 'paths == "item1" && type == "string" && string @ "10000" '::text)</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> Planning time: 67.089 ms</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal;"><span style="background-color: rgba(255, 255, 255, 0);"> Execution time: 5006.551 ms</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal; font-family: ".SF UI Text"; color: rgb(69, 69, 69); min-height: 19.1px;"><span style="font-family: ".SFUIText"; font-size: 16pt;"></span><br></p></div><div dir="ltr"><br>2019/02/21 19:40、江上 秀樹 <<a href="mailto:egami****@ae*****">egami****@ae*****</a>>のメール:<br><br></div><blockquote type="cite"><div dir="ltr"><span>堀本さま</span><br><span></span><br><span>江上です。</span><br><span></span><br><span>丁寧に解説いただき、ありがとうございました。インデックスも前方一致には対応されること、Postgresの実行計画にも左右されることについて良く理解出来ました。</span><br><span></span><br><span>検証機で他の試験も実施しているため、直ぐの確認が出来ない状況ですが、可能性を説明いただいたお陰で、少し気持ちが楽になりました。ありがとうございます。</span><br><span></span><br><span>取り急ぎ、お礼まで。</span><br><span></span><br><span>2019/02/21 17:29、Horimoto Yasuhiro <<a href="mailto:horim****@clear*****">horim****@clear*****</a>>のメール:</span><br><span></span><br><blockquote type="cite"><span>こんにちは、堀本と申します。</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>通常のトークナイザ(TokenBigram)は数字、英字の区切れでトークナイズし</span><br></blockquote><blockquote type="cite"><span>、数字のみの項目は全体がトークンとしてインデックスに登録されるので、</span><br></blockquote><blockquote type="cite"><span>1つ目のご質問の前半は江上さんのご理解の通りです。</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>ご質問の後半ですが、インデックスにあるトークンと完全一致しない検索</span><br></blockquote><blockquote type="cite"><span>キーワードの時にインデックスを使って検索をするかどうかは、PostgreSQL</span><br></blockquote><blockquote type="cite"><span>のプランナー次第なので、完全一致しないキーワードだからといって、</span><br></blockquote><blockquote type="cite"><span>フルスキャンになるとは限りません。</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>もし、インデックスを使った検索をPostgreSQLのプランナーが選択した場合は、</span><br></blockquote><blockquote type="cite"><span>以下のような挙動になります。</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>まず、インデックスに登録されている数字に完全一致する数字を含むレコード</span><br></blockquote><blockquote type="cite"><span>がヒットします。</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>完全一致でヒットしたレコードが存在した場合は、部分一致での検索はしない</span><br></blockquote><blockquote type="cite"><span>ため、部分一致しているレコードはヒットしません。</span><br></blockquote><blockquote type="cite"><span>(Groongaの全文検索は基本的に完全一致で検索するためです。)</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>デフォルトの設定では、完全一致でヒットするレコードが無かった場合は、</span><br></blockquote><blockquote type="cite"><span>前方一致検索を実施します。(少し緩めの検索をします)</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>したがって、インデックスを使った検索が選択された場合は、完全一致 -></span><br></blockquote><blockquote type="cite"><span>前方一致で検索され、完全一致、前方一致しないレコードはヒットしない。</span><br></blockquote><blockquote type="cite"><span>となります。</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>2つ目のご質問の「TokenBigramSplitSymbolAlphaDigit」を使うことである程度</span><br></blockquote><blockquote type="cite"><span>の高速化が見込めるかどうかなのですが、こちらは状況によるかと思います。</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>問題のクエリーを EXPLAIN ANALYZE VERBOSE をつけて実行した時に</span><br></blockquote><blockquote type="cite"><span>フルスキャンになっていた場合は、「TokenBigramSplitSymbolAlphaDigit」を</span><br></blockquote><blockquote type="cite"><span>使うことでインデックスを使った検索が選択され高速化する可能性があります</span><br></blockquote><blockquote type="cite"><span>が、既にインデックスを使って検索していた場合は、どちらもインデックスを</span><br></blockquote><blockquote type="cite"><span>使用した検索なので、高速化は見込めないと思われます。</span><br></blockquote><blockquote type="cite"><span>(インデックスに登録されるトークンが2文字ずつになるので、ヒット数は増える</span><br></blockquote><blockquote type="cite"><span>と思います。)</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>したがって、まずは、検索が遅い時の実行計画(EXPLAIN ANALYZE VERBOSEの</span><br></blockquote><blockquote type="cite"><span>結果)を見てインデックスが使われている検索なのかどうかを確認してみると</span><br></blockquote><blockquote type="cite"><span>いうのはいかがでしょうか?</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>的を外した回答になっていたらすみません。</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>以上です。失礼いたします。</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><blockquote type="cite"><span>On 2019/02/20 14:35, 江上 秀樹 wrote:</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>以前、別件で質問させていただいた江上と申しますが、その節はありがとうございました。</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>今回は数字の検索処理時間についてになります。</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>7桁の数字が入ったjsonデータ800万件の検索対象データと検索キーの組合せで、以下のような検索時間がかかりました。</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>検索対象 検索キー 検索時間</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>半角 半角 8秒</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>全角 全角 数ミリ秒</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>--- 実行したクエリ ----</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>SELECT * FROM table WHERE</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>order_key_value_json operator(pgroonga.@@) 'paths == "item004"' </span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>order_key_value_json はjsonカラムで100項目のキーバリュー収容。item004はそのキーの1つ。</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>---</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>●確認なのですが、以下で正しいでしょうか?</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>通常のトークナイザ(TokenBigram)は数字、英字の区切れでトークナイズするため、上記のような数字のみの項目は全体としてインデックス作成され、部分一致はフルスキャンになる。</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>この場合アルファベットも数字も2文字ずつ区切るトークナイザーである</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>「TokenBigramSplitSymbolAlphaDigit」を使うことである程度の高速化が見込めるでしょうか?</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>_______________________________________________</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>groonga-dev mailing list</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span><a href="mailto:groon****@lists*****">groon****@lists*****</a></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span><a href="https://lists.osdn.me/mailman/listinfo/groonga-dev">https://lists.osdn.me/mailman/listinfo/groonga-dev</a></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>_______________________________________________</span><br></blockquote><blockquote type="cite"><span>groonga-dev mailing list</span><br></blockquote><blockquote type="cite"><span><a href="mailto:groon****@lists*****">groon****@lists*****</a></span><br></blockquote><blockquote type="cite"><span><a href="https://lists.osdn.me/mailman/listinfo/groonga-dev">https://lists.osdn.me/mailman/listinfo/groonga-dev</a></span><br></blockquote><span>_______________________________________________</span><br><span>groonga-dev mailing list</span><br><span><a href="mailto:groon****@lists*****">groon****@lists*****</a></span><br><span><a href="https://lists.osdn.me/mailman/listinfo/groonga-dev">https://lists.osdn.me/mailman/listinfo/groonga-dev</a></span><br></div></blockquote></body></html>