ืขืœ ืžื” EXPLAIN ืฉื•ืชืง ื•ืื™ืš ืœื’ืจื•ื ืœื–ื” ืœื“ื‘ืจ

ื”ืฉืืœื” ื”ืงืœืืกื™ืช ืฉืžืคืชื— ืžื‘ื™ื ืœ-DBA ืฉืœื• ืื• ื‘ืขืœ ืขืกืง ืžื‘ื™ื ืœื™ื•ืขืฅ PostgreSQL ื›ืžืขื˜ ืชืžื™ื“ ื ืฉืžืขืช ืื•ืชื• ื”ื“ื‘ืจ: "ืžื“ื•ืข ืœื•ืงื— ื›ืœ ื›ืš ื”ืจื‘ื” ื–ืžืŸ ืœื”ืฉืœื™ื ื‘ืงืฉื•ืช ื‘ืžืกื“ ื”ื ืชื•ื ื™ื?"

ืกื˜ ืžืกื•ืจืชื™ ืฉืœ ืกื™ื‘ื•ืช:

  • ืืœื’ื•ืจื™ืชื ืœื ื™ืขื™ืœ
    ื›ืืฉืจ ืืชื” ืžื—ืœื™ื˜ ืœื”ืฆื˜ืจืฃ ืœืžืกืคืจ CTEs ืขืœ ืคื ื™ ื›ืžื” ืขืฉืจื•ืช ืืœืคื™ ืจืฉื•ืžื•ืช
  • ืกื˜ื˜ื™ืกื˜ื™ืงื” ืžื™ื•ืฉื ืช
    ืื ื”ื”ืชืคืœื’ื•ืช ื‘ืคื•ืขืœ ืฉืœ ื”ื ืชื•ื ื™ื ื‘ื˜ื‘ืœื” ื›ื‘ืจ ืฉื•ื ื” ืžืื•ื“ ืžื–ื• ืฉื ืืกืคื” ืขืœ ื™ื“ื™ ANALYZE ื‘ืคืขื ื”ืงื•ื“ืžืช
  • "ืชืงืข" ืžืฉืื‘ื™ื
    ื•ื›ื‘ืจ ืื™ืŸ ืžืกืคื™ืง ื›ื•ื— ืžื—ืฉื•ื‘ ื™ื™ืขื•ื“ื™ ืฉืœ ื”ืžืขื‘ื“, ื’'ื™ื’ื”-ื‘ื™ื™ื˜ ืฉืœ ื–ื™ื›ืจื•ืŸ ื ืฉืื‘ ื›ืœ ื”ื–ืžืŸ, ืื• ืฉื”ื“ื™ืกืง ืœื ื™ื›ื•ืœ ืœืขืžื•ื“ ื‘ืงืฆื‘ ืฉืœ ื›ืœ ื”"ืจืฆื•ื ื•ืช" ืฉืœ ืžืกื“ ื”ื ืชื•ื ื™ื
  • ื—ืกื™ืžื” ืžืชื”ืœื™ื›ื™ื ืžืชื—ืจื™ื

ื•ืื ื“ื™ ืงืฉื” ืœืชืคื•ืก ื•ืœื ืชื— ื—ืกื™ืžื•ืช, ืื– ืœื›ืœ ื”ืฉืืจ ืฉืื ื—ื ื• ืฆืจื™ื›ื™ื ืชื•ื›ื ื™ืช ืฉืื™ืœืชื•ืช, ืฉื ื™ืชืŸ ืœื”ืฉื™ื’ ื‘ืืžืฆืขื•ืช ืื•ืคืจื˜ื•ืจ ื”ืกื‘ืจ (ืขื“ื™ืฃ, ื›ืžื•ื‘ืŸ, ืžื™ื“ ืœื”ืกื‘ื™ืจ (ืœื ืชื—, ืœื—ืฆืฅ) ...) ืื• ืžื•ื“ื•ืœ auto_explain.

ืื‘ืœ, ื›ืคื™ ืฉื ืืžืจ ื‘ืื•ืชื• ืชื™ืขื•ื“,

"ื”ื‘ื ืช ืชื•ื›ื ื™ืช ื”ื™ื ืืžื ื•ืช, ื•ื›ื“ื™ ืœืฉืœื•ื˜ ื‘ื” ื ื“ืจืฉืช ืžื™ื“ื” ืžืกื•ื™ืžืช ืฉืœ ื ื™ืกื™ื•ืŸ..."

ืื‘ืœ ืืชื” ื™ื›ื•ืœ ืœื”ืกืชื“ืจ ื‘ืœืขื“ื™ื• ืื ืืชื” ืžืฉืชืžืฉ ื‘ื›ืœื™ ื”ื ื›ื•ืŸ!

ืื™ืš ื ืจืื™ืช ื‘ื“ืจืš ื›ืœืœ ืชื•ื›ื ื™ืช ืฉืื™ืœืชื•ืช? ืžืฉื”ื• ื›ื–ื”:

Index Scan using pg_class_relname_nsp_index on pg_class (actual time=0.049..0.050 rows=1 loops=1)
  Index Cond: (relname = $1)
  Filter: (oid = $0)
  Buffers: shared hit=4
  InitPlan 1 (returns $0,$1)
    ->  Limit (actual time=0.019..0.020 rows=1 loops=1)
          Buffers: shared hit=1
          ->  Seq Scan on pg_class pg_class_1 (actual time=0.015..0.015 rows=1 loops=1)
                Filter: (relkind = 'r'::"char")
                Rows Removed by Filter: 5
                Buffers: shared hit=1

ืื• ื›ื›ื”:

"Append  (cost=868.60..878.95 rows=2 width=233) (actual time=0.024..0.144 rows=2 loops=1)"
"  Buffers: shared hit=3"
"  CTE cl"
"    ->  Seq Scan on pg_class  (cost=0.00..868.60 rows=9972 width=537) (actual time=0.016..0.042 rows=101 loops=1)"
"          Buffers: shared hit=3"
"  ->  Limit  (cost=0.00..0.10 rows=1 width=233) (actual time=0.023..0.024 rows=1 loops=1)"
"        Buffers: shared hit=1"
"        ->  CTE Scan on cl  (cost=0.00..997.20 rows=9972 width=233) (actual time=0.021..0.021 rows=1 loops=1)"
"              Buffers: shared hit=1"
"  ->  Limit  (cost=10.00..10.10 rows=1 width=233) (actual time=0.117..0.118 rows=1 loops=1)"
"        Buffers: shared hit=2"
"        ->  CTE Scan on cl cl_1  (cost=0.00..997.20 rows=9972 width=233) (actual time=0.001..0.104 rows=101 loops=1)"
"              Buffers: shared hit=2"
"Planning Time: 0.634 ms"
"Execution Time: 0.248 ms"

ืื‘ืœ ืœืงืจื•ื ืืช ื”ืชื•ื›ื ื™ืช ื‘ื˜ืงืกื˜ "ืžื”ื’ื™ืœื™ื•ืŸ" ืงืฉื” ืžืื•ื“ ื•ืœื ื‘ืจื•ืจ:

  • ืžื•ืฆื’ ื‘ืฆื•ืžืช ืกื›ื•ื ืœืคื™ ืžืฉืื‘ื™ ืชืช-ืขืฅ
    ื›ืœื•ืžืจ, ื›ื“ื™ ืœื”ื‘ื™ืŸ ื›ืžื” ื–ืžืŸ ืœืงื— ืœื”ืคืขื™ืœ ืฆื•ืžืช ืžืกื•ื™ื, ืื• ื›ืžื” ื‘ื“ื™ื•ืง ื”ืงืจื™ืื” ื”ื–ื• ืžื”ื˜ื‘ืœื” ื”ืขืœืชื” ื ืชื•ื ื™ื ืžื”ื“ื™ืกืง, ืืชื” ืฆืจื™ืš ืื™ื›ืฉื”ื• ืœื”ื—ืกื™ืจ ืื—ื“ ืžื”ืฉื ื™
  • ื™ืฉ ืฆื•ืจืš ื‘ื–ืžืŸ ื”ืฆื•ืžืช ืœื”ื›ืคื™ืœ ื‘ืœื•ืœืื•ืช
    ื›ืŸ, ื—ื™ืกื•ืจ ื”ื™ื ืœื ื”ืคืขื•ืœื” ื”ื›ื™ ืžื•ืจื›ื‘ืช ืฉืฆืจื™ืš ืœืขืฉื•ืช "ื‘ืจืืฉ" - ืื—ืจื™ ื”ื›ืœ, ื–ืžืŸ ื”ื‘ื™ืฆื•ืข ืžืฆื•ื™ืŸ ื›ืžืžื•ืฆืข ืœื‘ื™ืฆื•ืข ืื—ื“ ืฉืœ ืฆื•ืžืช, ื•ื™ื›ื•ืœื™ื ืœื”ื™ื•ืช ืžืื•ืช ืžื”ื
  • ื•ื‘ื›ืŸ, ื•ื›ืœ ื–ื” ื‘ื™ื—ื“ ืžื•ื ืข ืžืื™ืชื ื• ืœืขื ื•ืช ืขืœ ื”ืฉืืœื” ื”ืžืจื›ื–ื™ืช - ืื– ืžื™ "ื”ื—ื•ืœื™ื” ื”ื—ืœืฉื” ื‘ื™ื•ืชืจ"?

ื›ืฉื ื™ืกื™ื ื• ืœื”ืกื‘ื™ืจ ืืช ื›ืœ ื–ื” ืœื›ืžื” ืžืื•ืช ืžื”ืžืคืชื—ื™ื ืฉืœื ื•, ื”ื‘ื ื• ืฉืžื‘ื—ื•ืฅ ื–ื” ื ืจืื” ื‘ืขืจืš ื›ืš:

ืขืœ ืžื” EXPLAIN ืฉื•ืชืง ื•ืื™ืš ืœื’ืจื•ื ืœื–ื” ืœื“ื‘ืจ

ื•ื–ื” ืื•ืžืจ ืฉืื ื—ื ื• ืฆืจื™ื›ื™ื...

ื›ืœื™

ื‘ื• ื ื™ืกื™ื ื• ืœืืกื•ืฃ ืืช ื›ืœ ื”ืžื›ื ื™ืงื” ื”ืžืจื›ื–ื™ืช ืฉืขื•ื–ืจืช ืœื”ื‘ื™ืŸ "ืžื™ ืืฉื ื•ืžื” ืœืขืฉื•ืช" ืœืคื™ ื”ืชื•ื›ื ื™ืช ื•ื”ื‘ืงืฉื”. ื•ื‘ื›ืŸ, ื•ืฉืชืฃ ื—ืœืง ืžื”ื—ื•ื•ื™ื” ืฉืœืš ืขื ื”ืงื”ื™ืœื”.
ืคื’ื•ืฉ ื•ื”ืฉืชืžืฉ - explain.tensor.ru

ื ืจืื•ืช ืฉืœ ืชื•ื›ื ื™ื•ืช

ื”ืื ืงืœ ืœื”ื‘ื™ืŸ ืืช ื”ืชื•ื›ื ื™ืช ื›ืฉื”ื™ื ื ืจืื™ืช ื›ืš?

Seq Scan on pg_class (actual time=0.009..1.304 rows=6609 loops=1)
  Buffers: shared hit=263
Planning Time: 0.108 ms
Execution Time: 1.800 ms

ืœื ืžืžืฉ.

ืื‘ืœ ื›ื›ื”, ื‘ืฆื•ืจื” ืžืงื•ืฆืจืชื›ืฉืžื“ื“ื™ ื”ืžืคืชื— ืžื•ืคืจื“ื™ื, ื–ื” ื”ืจื‘ื” ื™ื•ืชืจ ื‘ืจื•ืจ:

ืขืœ ืžื” EXPLAIN ืฉื•ืชืง ื•ืื™ืš ืœื’ืจื•ื ืœื–ื” ืœื“ื‘ืจ

ืื‘ืœ ืื ื”ืชื•ื›ื ื™ืช ืชื”ื™ื” ืžืกื•ื‘ื›ืช ื™ื•ืชืจ, ื”ื•ื ื™ื‘ื•ื ืœืขื–ืจื” ื—ืœื•ืงืช ื–ืžืŸ ืฉืœ piechart ืœืคื™ ืฆืžืชื™ื:

ืขืœ ืžื” EXPLAIN ืฉื•ืชืง ื•ืื™ืš ืœื’ืจื•ื ืœื–ื” ืœื“ื‘ืจ

ื•ื‘ื›ืŸ, ืœืืคืฉืจื•ื™ื•ืช ื”ืงืฉื•ืช ื‘ื™ื•ืชืจ ื”ื•ื ืžืžื”ืจ ืœืขื–ื•ืจ ื˜ื‘ืœืช ื”ืชืงื“ืžื•ืช:

ืขืœ ืžื” EXPLAIN ืฉื•ืชืง ื•ืื™ืš ืœื’ืจื•ื ืœื–ื” ืœื“ื‘ืจ

ืœื“ื•ื’ืžื”, ื™ืฉื ื ืžืฆื‘ื™ื ื“ื™ ืœื ื˜ืจื™ื•ื•ื™ืืœื™ื™ื ื›ืืฉืจ ืœืชื•ื›ื ื™ืช ืขืฉื•ื™ื” ืœื”ื™ื•ืช ื™ื•ืชืจ ืžืฉื•ืจืฉ ืื—ื“ ื‘ืคื•ืขืœ:

ืขืœ ืžื” EXPLAIN ืฉื•ืชืง ื•ืื™ืš ืœื’ืจื•ื ืœื–ื” ืœื“ื‘ืจืขืœ ืžื” EXPLAIN ืฉื•ืชืง ื•ืื™ืš ืœื’ืจื•ื ืœื–ื” ืœื“ื‘ืจ

ืจืžื–ื™ื ืžื‘ื ื™ื™ื

ื•ื‘ื›ืŸ, ืื ื›ืœ ืžื‘ื ื” ื”ืชื•ื›ื ื™ืช ื•ื”ื ืงื•ื“ื•ืช ื”ื›ื•ืื‘ื•ืช ืฉืœื” ื›ื‘ืจ ืžื•ื ื—ื•ืช ื•ื’ืœื•ื™ื•ืช, ืœืžื” ืœื ืœื”ื“ื’ื™ืฉ ืื•ืชื ืœื™ื–ื ื•ืœื”ืกื‘ื™ืจ ืื•ืชื ื‘"ืฉืคื” ื”ืจื•ืกื™ืช"?

ืขืœ ืžื” EXPLAIN ืฉื•ืชืง ื•ืื™ืš ืœื’ืจื•ื ืœื–ื” ืœื“ื‘ืจื›ื‘ืจ ืืกืคื ื• ื›ืžื” ืชืจื™ืกืจ ืชื‘ื ื™ื•ืช ื”ืžืœืฆื•ืช ื›ืืœื”.

ืคืจื•ืคื™ืœ ืฉืื™ืœืชื•ืช ืฉื•ืจื” ืื—ืจ ืฉื•ืจื”

ื›ืขืช, ืื ืชืฆืžื™ื“ ืืช ื”ืฉืื™ืœืชื” ื”ืžืงื•ืจื™ืช ืขืœ ื”ืชื•ื›ื ื™ืช ื”ืžื ื•ืชื—ืช, ืชื•ื›ืœ ืœืจืื•ืช ื›ืžื” ื–ืžืŸ ื”ื•ืฉืงืข ื‘ื›ืœ ื”ืฆื”ืจื” ื‘ื ืคืจื“ - ืžืฉื”ื• ื›ืžื• ื–ื”:

ืขืœ ืžื” EXPLAIN ืฉื•ืชืง ื•ืื™ืš ืœื’ืจื•ื ืœื–ื” ืœื“ื‘ืจ

...ืื• ืืคื™ืœื• ื›ื›ื”:

ืขืœ ืžื” EXPLAIN ืฉื•ืชืง ื•ืื™ืš ืœื’ืจื•ื ืœื–ื” ืœื“ื‘ืจ

ื”ื—ืœืคืช ืคืจืžื˜ืจื™ื ืœื‘ืงืฉื”

ืื "ืฆื™ืจืคืช" ืœื ืจืง ื‘ืงืฉื” ืœืชื•ื›ื ื™ืช, ืืœื ื’ื ืืช ื”ืคืจืžื˜ืจื™ื ืฉืœื” ืžืฉื•ืจืช DETAIL ืฉืœ ื”ื™ื•ืžืŸ, ืชื•ื›ืœ ื‘ื ื•ืกืฃ ืœื”ืขืชื™ืง ืื•ืชื” ื‘ืื—ืช ืžื”ืืคืฉืจื•ื™ื•ืช:

  • ืขื ื”ื—ืœืคืช ืขืจื›ื™ื ื‘ื‘ืงืฉื”
    ืœื‘ื™ืฆื•ืข ื™ืฉื™ืจ ืขืœ ื”ื‘ืกื™ืก ืฉืœืš ื•ืคืจื•ืคื™ืœ ื ื•ืกืฃ

    SELECT 'const', 'param'::text;
  • ืขื ื”ื—ืœืคืช ืขืจืš ื‘ืืžืฆืขื•ืช PREPARE/EXECUTE
    ื›ื“ื™ ืœื—ืงื•ืช ืืช ื”ืขื‘ื•ื“ื” ืฉืœ ื”ืžืชื–ืžืŸ, ื›ืืฉืจ ื ื™ืชืŸ ืœื”ืชืขืœื ืžื”ื—ืœืง ื”ืคืจืžื˜ืจื™ - ืœืžืฉืœ, ื›ืืฉืจ ืขื•ื‘ื“ื™ื ืขืœ ื˜ื‘ืœืื•ืช ืžื—ื•ืœืงื•ืช

    DEALLOCATE ALL;
    PREPARE q(text) AS SELECT 'const', $1::text;
    EXECUTE q('param'::text);
    

ืืจื›ื™ื•ืŸ ืชื•ื›ื ื™ื•ืช

ื”ื“ื‘ืง, ื ืชื—, ืฉืชืฃ ืขื ืขืžื™ืชื™ื! ื”ืชื•ื›ื ื™ื•ืช ื™ื™ืฉืืจื• ื‘ืืจื›ื™ื•ืŸ ื•ืชื•ื›ืœ ืœื—ื–ื•ืจ ืืœื™ื”ืŸ ืžืื•ื—ืจ ื™ื•ืชืจ: explain.tensor.ru/archive

ืื‘ืœ ืื ืืชื” ืœื ืจื•ืฆื” ืฉืื—ืจื™ื ื™ืจืื• ืืช ื”ืชื•ื›ื ื™ืช ืฉืœืš, ืืœ ืชืฉื›ื— ืœืกืžืŸ ืืช ื”ืชื™ื‘ื” "ืืœ ืชืคืจืกื ื‘ืืจื›ื™ื•ืŸ".

ื‘ืžืืžืจื™ื ื”ื‘ืื™ื ืื“ื‘ืจ ืขืœ ื”ืงืฉื™ื™ื ื•ื”ื”ื—ืœื˜ื•ืช ืฉืขื•ืœื•ืช ื‘ืขืช ื ื™ืชื•ื— ืชื›ื ื™ืช.

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”