こんにちは、堀本です。
回答が遅くなってしまい申し訳ありません。
あまり、ぱっとした改善案は思いつきませんでしたが、もしかしたら
条件を並び替えることで高速化できるかもしれません。
以下の手順で出力されるPGroongaのクエリーログの内容を教えていただ
けないでしょうか?
1. PostgreSQLに接続し、以下のSETコマンドを実行して下さい。
SET pgroonga.query_log_path = 'pgroonga.query.log';
2. 上記のコマンドを実行後、遅いクエリーを実行して下さい。
3. 上記のクエリー実行後、PGDATA/pgroonga.query.log の内容を教えて
頂ければと思います。
(PGDATA はPostgreSQLのデータディレクトリを表します。
例えば、PostgreSQL9.6ならPGDATAはデフォルトで
/var/lib/pgsql/9.6/data です。)
また、@@ 演算子を使用されているようですが、この演算子は、後方互換のため
に残しているだけの非推奨な演算子ですので、もしPGroonga1.2.1以降をお使い
でしたら、&`演算子をお使い頂いたほうが良いかと思います。
&`演算子については、以下にドキュメントが有りますので
必要に応じてご参照頂ければと思います。
https://pgroonga.github.io/ja/reference/operators/script-jsonb-v2.html
以上です。失礼いたします。
On 2019/03/11 0:11, 江上 秀樹 wrote:
> 堀本さま
>
>
> 2月下旬に
>
> 「TokenBigramSplitSymbolAlphaDigit」に関して質問していた江上です。
>
>
> インデックスに上記を適用した際の実行計画を取得してみましたが、5秒程度か
> かっています。これ以上のチューニング方法はドキュメント上無いように思いま
> すが、他に試す方法があるようであれば、ご教授いただけないかと思っています。
>
>
> 今回の利用では、画面上の全項目を部分一致検索対象としていますが、そもそ
> も、数字7桁に対して、部分一致検索する用途があるのか、という話もあるです
> が。。
>
>
> 【テーブル】
>
> table:約700万件
>
> order_key_value_jsonの中に数十のkey-valueが有り、item004のキーに7桁の数
> 字が入る。
>
>
> 列 型
>
> sys_no character varying(10)
>
> order_key_value_json jsonb
>
> インデックス:
>
> "table_i1" pgroonga (order_key_value_json) WITH
> (tokenizer='TokenBigramSplitSymbolAlphaDigit')
>
>
> 【実行SQL】
>
> SELECT sys_no FROM table WHERE
>
> order_key_value_json operator(pgroonga.@@) 'paths == "item004" &&
> type == "string" && string @ "10000" ';
>
>
> 【QUERY PLAN】
>
> 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)
>
> Output: sys_no
>
> Recheck Cond: (table.order_key_value_json OPERATOR(pgroonga.@@)
> 'paths == "item004" && type == "string" && string @ "10000" '::text)
>
> Heap Blocks: exact=179
>
> -> 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)
>
> Index Cond: (table.order_key_value_json OPERATOR(pgroonga.@@)
> 'paths == "item1" && type == "string" && string @ "10000" '::text)
>
> Planning time: 67.089 ms
>
> Execution time: 5006.551 ms
>
>
>
> 2019/02/21 19:40、江上 秀樹 <egami****@ae*****
> <mailto:egami****@ae*****>>のメール:
>
>> 堀本さま
>>
>> 江上です。
>>
>> 丁寧に解説いただき、ありがとうございました。インデックスも前方一致には
>> 対応されること、Postgresの実行計画にも左右されることについて良く理解出
>> 来ました。
>>
>> 検証機で他の試験も実施しているため、直ぐの確認が出来ない状況ですが、可
>> 能性を説明いただいたお陰で、少し気持ちが楽になりました。ありがとうござ
>> います。
>>
>> 取り急ぎ、お礼まで。
>>
>> 2019/02/21 17:29、Horimoto Yasuhiro <horim****@clear*****
>> <mailto:horim****@clear*****>>のメール:
>>
>>> こんにちは、堀本と申します。
>>>
>>> 通常のトークナイザ(TokenBigram)は数字、英字の区切れでトークナイズし
>>> 、数字のみの項目は全体がトークンとしてインデックスに登録されるので、
>>> 1つ目のご質問の前半は江上さんのご理解の通りです。
>>>
>>> ご質問の後半ですが、インデックスにあるトークンと完全一致しない検索
>>> キーワードの時にインデックスを使って検索をするかどうかは、PostgreSQL
>>> のプランナー次第なので、完全一致しないキーワードだからといって、
>>> フルスキャンになるとは限りません。
>>>
>>> もし、インデックスを使った検索をPostgreSQLのプランナーが選択した場合は、
>>> 以下のような挙動になります。
>>>
>>> まず、インデックスに登録されている数字に完全一致する数字を含むレコード
>>> がヒットします。
>>>
>>> 完全一致でヒットしたレコードが存在した場合は、部分一致での検索はしない
>>> ため、部分一致しているレコードはヒットしません。
>>> (Groongaの全文検索は基本的に完全一致で検索するためです。)
>>>
>>> デフォルトの設定では、完全一致でヒットするレコードが無かった場合は、
>>> 前方一致検索を実施します。(少し緩めの検索をします)
>>>
>>> したがって、インデックスを使った検索が選択された場合は、完全一致 ->
>>> 前方一致で検索され、完全一致、前方一致しないレコードはヒットしない。
>>> となります。
>>>
>>>
>>> 2つ目のご質問の「TokenBigramSplitSymbolAlphaDigit」を使うことである程度
>>> の高速化が見込めるかどうかなのですが、こちらは状況によるかと思います。
>>>
>>> 問題のクエリーを EXPLAIN ANALYZE VERBOSE をつけて実行した時に
>>> フルスキャンになっていた場合は、「TokenBigramSplitSymbolAlphaDigit」を
>>> 使うことでインデックスを使った検索が選択され高速化する可能性があります
>>> が、既にインデックスを使って検索していた場合は、どちらもインデックスを
>>> 使用した検索なので、高速化は見込めないと思われます。
>>> (インデックスに登録されるトークンが2文字ずつになるので、ヒット数は増える
>>> と思います。)
>>>
>>> したがって、まずは、検索が遅い時の実行計画(EXPLAIN ANALYZE VERBOSEの
>>> 結果)を見てインデックスが使われている検索なのかどうかを確認してみると
>>> いうのはいかがでしょうか?
>>>
>>> 的を外した回答になっていたらすみません。
>>>
>>> 以上です。失礼いたします。
>>>
>>>> On 2019/02/20 14:35, 江上 秀樹 wrote:
>>>> 以前、別件で質問させていただいた江上と申しますが、その節はありがとう
>>>> ございました。
>>>>
>>>> 今回は数字の検索処理時間についてになります。
>>>>
>>>> 7桁の数字が入ったjsonデータ800万件の検索対象データと検索キーの組合せ
>>>> で、以下のような検索時間がかかりました。
>>>>
>>>> 検索対象 検索キー 検索時間
>>>> 半角 半角 8秒
>>>> 全角 全角 数ミリ秒
>>>>
>>>> --- 実行したクエリ ----
>>>> SELECT * FROM table WHERE
>>>> order_key_value_json operator(pgroonga.@@) 'paths == "item004"'
>>>>
>>>> order_key_value_json はjsonカラムで100項目のキーバリュー収容。
>>>> item004はそのキーの1つ。
>>>> ---
>>>>
>>>> ●確認なのですが、以下で正しいでしょうか?
>>>>
>>>> 通常のトークナイザ(TokenBigram)は数字、英字の区切れでトークナイズす
>>>> るため、上記のような数字のみの項目は全体としてインデックス作成され、
>>>> 部分一致はフルスキャンになる。
>>>>
>>>> この場合アルファベットも数字も2文字ずつ区切るトークナイザーである
>>>> 「TokenBigramSplitSymbolAlphaDigit」を使うことである程度の高速化が見
>>>> 込めるでしょうか?
>>>>
>>>>
>>>> _______________________________________________
>>>> groonga-dev mailing list
>>>> groon****@lists***** <mailto:groon****@lists*****>
>>>> https://lists.osdn.me/mailman/listinfo/groonga-dev
>>>>
>>>
>>> _______________________________________________
>>> groonga-dev mailing list
>>> groon****@lists***** <mailto:groon****@lists*****>
>>> https://lists.osdn.me/mailman/listinfo/groonga-dev
>> _______________________________________________
>> groonga-dev mailing list
>> groon****@lists***** <mailto:groon****@lists*****>
>> https://lists.osdn.me/mailman/listinfo/groonga-dev
>
> _______________________________________________
> groonga-dev mailing list
> groon****@lists*****
> https://lists.osdn.me/mailman/listinfo/groonga-dev
>