Postgresql Postgres解释分析总时间似乎超过了各部分的总和

Postgresql Postgres解释分析总时间似乎超过了各部分的总和,postgresql,explain,database-optimization,Postgresql,Explain,Database Optimization,我试图找出Postgres查询中的一些性能瓶颈,并对一个查询运行解释分析,以获得一些见解。查询分析的输出如下: Nested Loop (cost=162.35..5361.39 rows=4385 width=33) (actual time=5.663..315.153 rows=2 loops=1) -> Seq Scan on "User" p=u (cost=0.00..1.02 rows=1 width=8) (actual time=0.009..0.011

我试图找出Postgres查询中的一些性能瓶颈,并对一个查询运行
解释分析
,以获得一些见解。查询分析的输出如下:

    Nested Loop  (cost=162.35..5361.39 rows=4385 width=33) (actual time=5.663..315.153 rows=2 loops=1)
  ->  Seq Scan on "User" p=u  (cost=0.00..1.02 rows=1 width=8) (actual time=0.009..0.011 rows=1 loops=1)
        Filter: ("ID" = 1)
        Rows Removed by Filter: 1
  ->  Nested Loop  (cost=162.35..5316.51 rows=4385 width=33) (actual time=5.646..315.130 rows=2 loops=1)
        ->  Nested Loop  (cost=161.93..1854.59 rows=6574 width=33) (actual time=5.567..106.350 rows=44342 loops=1)
              ->  Seq Scan on "Op" o  (cost=0.00..1.34 rows=1 width=8) (actual time=0.007..0.011 rows=1 loops=1)
                    Filter: ("Name" = 'write'::text)
                    Rows Removed by Filter: 26
              ->  Bitmap Heap Scan on "Account" a  (cost=161.93..1768.73 rows=8453 width=33) (actual time=5.551..45.435 rows=44342 loops=1)
                    Recheck Cond: ("OId" = o."ID")
                    Filter: ("UId" = 1)
                    Heap Blocks: exact=1480
                    ->  Bitmap Index Scan on "IX_Account_op_ID"  (cost=0.00..159.82 rows=8453 width=0) (actual time=5.138..5.139 rows=44342 loops=1)
                          Index Cond: ("OId" = o."ID")
        ->  Index Scan using "PK_Resource_ID" on "Resources" r  (cost=0.42..0.53 rows=1 width=8) (actual time=0.003..0.003 rows=0 loops=44342)
              Index Cond: ("ID" = a."ResourceId")
              Filter: ("Role" = ANY ('{r1,r2,r3,r4,r5}'::text[]))
              Rows Removed by Filter: 1
Planning Time: 0.777 ms
Execution Time: 315.220 ms
我以前没有用pg explain做过太多的查询分析,所以我仍然在试图理解它在这里告诉我的一切。我看到的一件让我感到困惑的事情是,我可以看到外部执行:

Nested Loop  (cost=162.35..5361.39 rows=4385 width=33) (actual time=5.663..315.153 rows=2 loops=1)
表示实际时间是5.663…315-好的,这是有意义的,因为总执行时间是315。然后,稍微低于该值:

嵌套循环(成本=162.35..5316.51行=4385宽度=33)(实际时间=5.646..315.130行=2个循环=1)

好的!这告诉我总执行时间的大部分将在这一部分。在此情况下,我看到:

    ->  Nested Loop  (cost=161.93..1854.59 rows=6574 width=33) (actual time=5.567..106.350 rows=44342 loops=1)
          ->  Seq Scan on "Op" o  (cost=0.00..1.34 rows=1 width=8) (actual time=0.007..0.011 rows=1 loops=1)
                Filter: ("Name" = 'write'::text)
                Rows Removed by Filter: 26
          ->  Bitmap Heap Scan on "Account" a  (cost=161.93..1768.73 rows=8453 width=33) (actual time=5.551..45.435 rows=44342 loops=1)
                Recheck Cond: ("OId" = o."ID")
                Filter: ("UId" = 1)
                Heap Blocks: exact=1480
嗯-这是说有一个嵌套循环,循环时间为
106.35 ms
,循环一次,循环内容是一个sq扫描,扫描时间为
.011ms
,位图堆扫描时间为
45.435ms

所有循环都有一个循环,但在这两种情况下,我觉得这些循环的总执行量都高于循环内容的总和。在内部循环的情况下,执行该循环需要
106ms
,但如果我将该循环的内容相加,它看起来应该只需要
45.446ms
(.011ms+45.435ms)
。在外循环的情况下,它花费了315.13ms
,但是如果我把内容加起来,它看起来应该是106.353ms
(106.35ms+0.003ms)


我正在看这个,并假设loops=1意味着它只执行了一次循环中的内容。。虽然总时间表明有不止一次执行。我不确定我在哪里误解了这一点。有人能帮我解释一下吗?如果您有任何建议,我们将不胜感激,谢谢

ANALYZE不显示在
从[…]选择任务中执行任务所需的时间。
。 这里的
pg_sleep(1)
需要20000ms(20x1s),但您只能在
Nested Loop
部分看到它

explain (analyze, verbose)
select *, pg_sleep(1)
  from generate_series(1,5) AS w
  cross join generate_series(current_date,current_date+3,interval '1 day') AS v;

QUERY PLAN
Nested Loop  (cost=0.02..22510.02 rows=1000000 width=16) (actual time=1001.082..20021.134 rows=20 loops=1)
  Output: w.w, v.v, pg_sleep('1'::double precision)
  ->  Function Scan on pg_catalog.generate_series w  (cost=0.00..10.00 rows=1000 width=4) (actual time=0.006..0.008 rows=5 loops=1)
        Output: w.w
        Function Call: generate_series(1, 5)
  ->  Function Scan on pg_catalog.generate_series v  (cost=0.02..10.02 rows=1000 width=8) (actual time=0.005..0.010 rows=4 loops=5)
        Output: v.v
        Function Call: generate_series((('now'::cstring)::date)::timestamp with time zone, ((('now'::cstring)::date + 3))::timestamp with time zone, '1 day'::interval)
Planning time: 0.093 ms
Execution time: 20021.178 ms
它不显示连接数据集所需的时间。在这里获取数据大约需要1000毫秒,但加入这些集合需要4倍的时间,因为您可以看到
嵌套循环
部分的时间增加了大约1000毫秒,这是它必须做的唯一一件事,并且没有在详细计划中列出

explain (analyze, verbose)
select *
  from generate_series(1,50000) AS w
  cross join generate_series(current_date,current_date+30,interval '1 day') AS v;

QUERY PLAN
Nested Loop  (cost=0.02..20010.02 rows=1000000 width=12) (actual time=3.237..3128.123 rows=1550000 loops=1)
  Output: w.w, v.v
  ->  Function Scan on pg_catalog.generate_series w  (cost=0.00..10.00 rows=1000 width=4) (actual time=3.210..35.472 rows=50000 loops=1)
        Output: w.w
        Function Call: generate_series(1, 50000)
  ->  Function Scan on pg_catalog.generate_series v  (cost=0.02..10.02 rows=1000 width=8) (actual time=0.001..0.021 rows=31 loops=50000)
        Output: v.v
        Function Call: generate_series((('now'::cstring)::date)::timestamp with time zone, ((('now'::cstring)::date + 30))::timestamp with time zone, '1 day'::interval)
Planning time: 0.046 ms
Execution time: 4103.113 ms

只是猜测,并行处理计划的某些分支?您是否在选择中执行某些操作,例如数学操作、函数执行或其他需要时间的操作?