Postgresql Postgres解释分析总时间似乎超过了各部分的总和
我试图找出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
解释分析,以获得一些见解。查询分析的输出如下:
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
只是猜测,并行处理计划的某些分支?您是否在选择中执行某些操作,例如数学操作、函数执行或其他需要时间的操作?