我有一个查询,当在我的PostgreSQL数据库上运行时,会随着它们的数量增加而不断增加执行时间.在高负载期间,我使用解释分析从Dbeaver手动运行相同的查询,计划时间约为9秒,执行时间约为1秒.但是,如果我将结果查询中的所有实际时间相加,我得不到接近9秒的结果.

我也没有多个循环.以下是解释分析结果:

Nested Loop Left Join  (cost=26304.72..35480113.45 rows=624544385412 width=1843) (actual time=0.277..0.284 rows=1 loops=1)
  ->  Nested Loop  (cost=26304.15..907648.85 rows=320874 width=1495) (actual time=0.215..0.218 rows=1 loops=1)
        ->  Index Scan using idx_info_part_13_test_id on test_part_13 "Model"  (cost=0.69..8.71 rows=1 width=976) (actual time=0.140..0.142 rows=1 loops=1)
              Index Cond: ((test_id)::text = 'sjbvas6dsad4sad7asda7sd567as5f7dsdf75sdfsdf6sdf5sfas78d6fdsdsada'::text)
        ->  Bitmap Heap Scan on outputs_p_33 "Model"  (cost=26303.46..904431.40 rows=320874 width=519) (actual time=0.060..0.061 rows=1 loops=1)
              Recheck Cond: ((test_id)::text = 'sjbvas6dsad4sad7asda7sd567as5f7dsdf75sdfsdf6sdf5sfas78d6fdsdsada'::text)
              Heap Blocks: exact=1
              ->  Bitmap Index Scan on pk_test_p_33  (cost=0.00..26223.24 rows=320874 width=0) (actual time=0.055..0.055 rows=1 loops=1)
                    Index Cond: ((test_id)::text = 'sjbvas6dsad4sad7asda7sd567as5f7dsdf75sdfsdf6sdf5sfas78d6fdsdsada'::text)
  ->  Append  (cost=0.56..107.54 rows=20 width=348) (actual time=0.046..0.049 rows=1 loops=1)
        ->  Index Scan using addresses_part_0_address_id_idx on addresses_part_0 "ModelType"  (cost=0.56..5.37 rows=1 width=348) (never executed)
              Index Cond: ((address_id)::text = ("Model".address_id)::text)
        ->  Index Scan using addresses_part_1_address_id_idx on addresses_part_1 "ModelType_1"  (cost=0.56..5.37 rows=1 width=348) (never executed)
              Index Cond: ((address_id)::text = ("Model".address_id)::text)
        ->  Index Scan using addresses_part_2_address_id_idx on addresses_part_2 "ModelType_2"  (cost=0.56..5.37 rows=1 width=348) (never executed)
              Index Cond: ((address_id)::text = ("Model".address_id)::text)
        ->  Index Scan using addresses_part_3_address_id_idx on addresses_part_3 "ModelType_3"  (cost=0.56..5.37 rows=1 width=348) (never executed)
              Index Cond: ((address_id)::text = ("Model".address_id)::text)
        ->  Index Scan using addresses_part_4_address_id_idx on addresses_part_4 "ModelType_4"  (cost=0.56..5.37 rows=1 width=348) (never executed)
              Index Cond: ((address_id)::text = ("Model".address_id)::text)
        ->  Index Scan using addresses_part_5_address_id_idx on addresses_part_5 "ModelType_5"  (cost=0.56..5.37 rows=1 width=348) (never executed)
              Index Cond: ((address_id)::text = ("Model".address_id)::text)
        ->  Index Scan using addresses_part_6_address_id_idx on addresses_part_6 "ModelType_6"  (cost=0.56..5.37 rows=1 width=348) (actual time=0.042..0.042 rows=1 loops=1)
              Index Cond: ((address_id)::text = ("Model".address_id)::text)
        ->  Index Scan using addresses_part_7_address_id_idx on addresses_part_7 "ModelType_7"  (cost=0.56..5.37 rows=1 width=348) (never executed)
              Index Cond: ((address_id)::text = ("Model".address_id)::text)
        ->  Index Scan using addresses_part_8_address_id_idx on addresses_part_8 "ModelType_8"  (cost=0.56..5.37 rows=1 width=348) (never executed)
              Index Cond: ((address_id)::text = ("Model".address_id)::text)
        ->  Index Scan using addresses_part_9_address_id_idx on addresses_part_9 "ModelType_9"  (cost=0.56..5.37 rows=1 width=348) (never executed)
              Index Cond: ((address_id)::text = ("Model".address_id)::text)
        ->  Index Scan using addresses_part_10_address_id_idx on addresses_part_10 "ModelType_10"  (cost=0.56..5.37 rows=1 width=348) (never executed)
              Index Cond: ((address_id)::text = ("Model".address_id)::text)
        ->  Index Scan using addresses_part_11_address_id_idx on addresses_part_11 "ModelType_11"  (cost=0.56..5.37 rows=1 width=348) (never executed)
              Index Cond: ((address_id)::text = ("Model".address_id)::text)
        ->  Index Scan using addresses_part_12_address_id_idx on addresses_part_12 "ModelType_12"  (cost=0.56..5.37 rows=1 width=348) (never executed)
              Index Cond: ((address_id)::text = ("Model".address_id)::text)
        ->  Index Scan using addresses_part_13_address_id_idx on addresses_part_13 "ModelType_13"  (cost=0.56..5.37 rows=1 width=348) (never executed)
              Index Cond: ((address_id)::text = ("Model".address_id)::text)
        ->  Index Scan using addresses_part_14_address_id_idx on addresses_part_14 "ModelType_14"  (cost=0.56..5.37 rows=1 width=348) (never executed)
              Index Cond: ((address_id)::text = ("Model".address_id)::text)
        ->  Index Scan using addresses_part_15_address_id_idx on addresses_part_15 "ModelType_15"  (cost=0.56..5.37 rows=1 width=348) (never executed)
              Index Cond: ((address_id)::text = ("Model".address_id)::text)
        ->  Index Scan using addresses_part_16_address_id_idx on addresses_part_16 "ModelType_16"  (cost=0.56..5.37 rows=1 width=348) (never executed)
              Index Cond: ((address_id)::text = ("Model".address_id)::text)
        ->  Index Scan using addresses_part_17_address_id_idx on addresses_part_17 "ModelType_17"  (cost=0.56..5.37 rows=1 width=348) (never executed)
              Index Cond: ((address_id)::text = ("Model".address_id)::text)
        ->  Index Scan using addresses_part_18_address_id_idx on addresses_part_18 "ModelType_18"  (cost=0.56..5.37 rows=1 width=348) (never executed)
              Index Cond: ((address_id)::text = ("Model".address_id)::text)
        ->  Index Scan using addresses_part_19_address_id_idx on addresses_part_19 "ModelType_19"  (cost=0.56..5.37 rows=1 width=348) (never executed)
              Index Cond: ((address_id)::text = ("Model".address_id)::text)
Planning Time: 9127.562 ms
Execution Time: 1.090 ms

如果我从结果中加上"实际时间",我不是应该得到相同的秒数吗?为什么会有这么大的差别?

推荐答案

  1. 使用this判断您的执行计划.
  2. These don't add up because they don't have to. From Using EXPLAIN in the doc:

    EXPLAIN ANALYZE所示的Planning time是从解析的查询生成查询计划并对其进行优化所花费的时间.它不包括解析或重写.

    EXPLAIN ANALYZE所示的Execution time包括执行器启动和关闭时间,以及运行所触发的任何触发器的时间

  3. The doc explains what those measurements are exactly:

    在[嵌套循环计划]中,循环值报告 node 的总执行次数,显示的实际时间和行值是每次执行的平均值

  4. auto_explain个可以用来自动捕获、记录和解释缓慢的查询.如果你想找出什么东西慢的原因,或者出于某种原因,当你单独运行并判断它的时候,它是很有用的.Auto_explain应该反映出为什么它慢了下来,以及到底是什么让它停滞不前.

通常,如果您遇到了因流量增加而导致的查询时间增加的情况,您可能会想看看是否没有

  • 锁定某些东西,导致并发会话不得不在队列中等待当前会话完成,
  • CPU/内存不足
  • 如果您在每个请求/响应中传输大量数据,则接近带宽限制
  • try 一次读写过多,对底层存储进行压力测试,可能无法跟上IO需求

这份 list 远非详尽无遗.需要服务器配置、模式、完整查询、数据集特征和流量配置文件才能对其进行调查.

Postgresql相关问答推荐

Postgres SQL执行加入

在Docker Compose中获取CSV文件数据?

如何确定要与给定转储文件一起使用的pg_Restore版本?

ANTLR4 PostgreSQL语法被 destruct 了吗?

列索引8上的扫描错误,名称已复制:不支持扫描,正在存储驱动程序.值类型[]uint8到类型*[]*bool

为什么Postgres在打印时能完全缩短时间跨度?

PostgreSQL 不删除旧的 WAL 档案

将数组的所有元素循环到jsonb中并修改值

Upper() 不会大写重音字符

在 PostgreSQL 中提高 GROUP BY ... HAVING COUNT(...) > 1 的性能

从 PostgreSQL 中的每个组中抽取 N 个样本

Postgresql JSONB 来了.现在用什么?Hstore?JSON?EAV?

包含受先前 DELETE 影响的行数的变量?

错误:syntax error at or near "user"

如何在 PostgreSQL 中创建 guid

如何在数据库表中查找重复条目?

Postgres 中是否有 MAX_INT 常量?

大型查询后 psycopg2 泄漏内存

在 postgresql 中对使用 array_agg 创建的文本聚合进行排序

PostgreSQL:从转储中恢复数据库 - 语法错误