日付で約70の子テーブルに分割されたテーブル(postgres 9.6)があります。
以下のEXPLAIN
の出力は、ほとんどが各子テーブルの同一のビットマップインデックス/ヒープスキャンであるため、切り捨てられています( フル、詳細な出力 )。私が興味のある部分は、ツリーの上部にあるAppend
およびResult
ノードです。
Append
は単にすべてのサブクエリの合計です。実際には、これより約3.5秒長くかかります。エキストラはどこから来ますか?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
Appendはバッファ管理を行う必要があります。また、EXPLAIN ANALYZEのタイミングコンポーネントを満たすために、いくつかのクロック関数(たとえば、gettimeofday
)を何度も呼び出します。そのオーバーヘッドが支配的な時間シンクになる可能性があります。
あなたの場合、ResultノードはSUBSTR関数の結果を計算しています。これは詳細プランの[出力]フィールドにあります。また、いくつかの時計機能を頻繁に呼び出しています。
explain (analyze, timing off)
を実行する場合、その実行時間から、EXPLAIN ANALYZEのどのくらいの時間がインストルメンテーションオーバーヘッドに向かっているのかがわかります。