web-dev-qa-db-ja.com

Postgresプランの「結果」ノードと「追加」で実際に何が起こっていますか?

日付で約70の子テーブルに分割されたテーブル(postgres 9.6)があります。

以下のEXPLAINの出力は、ほとんどが各子テーブルの同一のビットマップインデックス/ヒープスキャンであるため、切り捨てられています( フル、詳細な出力 )。私が興味のある部分は、ツリーの上部にあるAppendおよびResultノードです。

  1. 私が収集できたもの(たとえば here など)から、Appendは単にすべてのサブクエリの合計です。実際には、これより約3.5秒長くかかります。エキストラはどこから来ますか?
  2. 1つの参照 からResultまでの状態のみを検索できますこの操作は、クエリが定数値を選択するときに使用されます。このノードは約7秒かかりますが、クエリは定数値を選択しません。

できればこれらの10秒を節約したいのですが、実際にはこれらのノードが何をしているかわからないので、何を試したらよいかわかりません。

EXPLAIN ANALYZE出力:

  ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
  │                                                                                      QUERY PLAN                                                                                       │
  ├───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ HashAggregate  (cost=4459946.40..4473566.96 rows=1089645 width=64) (actual time=26289.308..26419.989 rows=190112 loops=1)                                                             │
  │   Group Key: frontend_prescription.processing_date, frontend_prescription.pct_id, substr((frontend_prescription.presentation_code)::text, 1, 9)                                       │
  │   Buffers: shared hit=172527                                                                                                                                                          │
  │   ->  Result  (cost=0.00..4296499.68 rows=10896448 width=60) (actual time=29.021..18762.432 rows=10769038 loops=1)                                                                    │
  │         Buffers: shared hit=172527                                                                                                                                                    │
  │         ->  Append  (cost=0.00..4160294.08 rows=10896448 width=44) (actual time=29.011..11454.952 rows=10769038 loops=1)                                                              │
  │               Buffers: shared hit=172527                                                                                                                                              │
  │               ->  Seq Scan on frontend_prescription  (cost=0.00..0.00 rows=1 width=88) (actual time=0.010..0.010 rows=0 loops=1)                                                      │
  │                     Filter: ((presentation_code)::text ~~ '0212%'::text)                                                                                                              │
  │               ->  Bitmap Heap Scan on frontend_prescription_201110  (cost=607.38..39094.77 rows=127148 width=44) (actual time=28.998..126.694 rows=183185 loops=1)                    │
  │                     Filter: ((presentation_code)::text ~~ '0212%'::text)                                                                                                              │
  │                     Heap Blocks: exact=2083                                                                                                                                           │
  │                     Buffers: shared hit=2788                                                                                                                                          │
  │                     ->  Bitmap Index Scan on idx_frontend_prescription_201110_presentation  (cost=0.00..575.59 rows=37356 width=0) (actual time=28.576..28.576 rows=183185 loops=1)   │
  │                           Index Cond: (((presentation_code)::text ~>=~ '0212'::text) AND ((presentation_code)::text ~<~ '0213'::text))                                                │
  │                           Buffers: shared hit=705
  <snip>    

クエリ:

EXPLAIN (ANALYZE,BUFFERS) SELECT
  processing_date,
  pct_id,
  SUBSTR(presentation_code, 1, 9) AS chemical_id,
  SUM(total_items) AS items,
  SUM(actual_cost) AS cost,
  SUM(quantity) AS quantity
FROM
  frontend_prescription
WHERE presentation_code LIKE '0212%'
GROUP BY
  processing_date,
  pct_id,
  chemical_id
4
seb

Appendはバッファ管理を行う必要があります。また、EXPLAIN ANALYZEのタイミングコンポーネントを満たすために、いくつかのクロック関数(たとえば、gettimeofday)を何度も呼び出します。そのオーバーヘッドが支配的な時間シンクになる可能性があります。

あなたの場合、ResultノードはSUBSTR関数の結果を計算しています。これは詳細プランの[出力]フィールドにあります。また、いくつかの時計機能を頻繁に呼び出しています。

explain (analyze, timing off)を実行する場合、その実行時間から、EXPLAIN ANALYZEのどのくらいの時間がインストルメンテーションオーバーヘッドに向かっているのかがわかります。

5
jjanes