我有一些应用程序可以打开一个事务并运行一个存储过程。 在存储过程中有一些“插入X选择Y”语句。 在某些情况下,存储过程需要一个多小时才能完成,而占用100%并且大部分时间都不执行IO。
当我尝试在相同的数据库/数据上运行psql中的存储过程时,需要一分钟。
通常我使用explain analyze来理解瓶颈但是因为它从psql中按预期运行,所以我有一个问题需要解决这里的问题。
有没有办法更好地理解为什么声明会被卡住?
也许启用一些日志来解释后端的内部工作?
服务器:PostgreSQL 9.2.4
以下是此CPU循环期间postgres的堆栈跟踪:
#0 0x080931d3 in slot_getattr ()
#1 0x081d3375 in ExecMakeFunctionResultNoSets ()
#2 0x081d382b in ExecQual ()
#3 0x081e4b3d in ExecNestLoop ()
#4 0x081cdbbd in ExecProcNode ()
#5 0x081e4a57 in ExecNestLoop ()
#6 0x081cdbbd in ExecProcNode ()
#7 0x081e3552 in ExecModifyTable ()
#8 0x081cdae4 in ExecProcNode ()
#9 0x081ccd71 in standard_ExecutorRun ()
#10 0xf78c5cf9 in pgss_ExecutorRun () from /opt/CPshrd- R80/database/postgresql/lib/postgresql/pg_stat_statements.so
#11 0x081ee9d5 in _SPI_execute_plan ()
#12 0x081eed1a in SPI_execute_plan_with_paramlist ()
#13 0x4db7f43d in exec_stmt_execsql () from /opt/CPshrd- R80/database/postgresql/lib/postgresql/plpgsql.so
#14 0x4db8169a in exec_stmt () from /opt/CPshrd-R80/database/postgresql/lib/postgresql/plpgsql.so
#15 0x4db825f3 in exec_stmts () from /opt/CPshrd-R80/database/postgresql/lib/postgresql/plpgsql.so
#16 0x4db81279 in exec_stmt_block () from /opt/CPshrd- R80/database/postgresql/lib/postgresql/plpgsql.so
#17 0x4db8454b in plpgsql_exec_function () from /opt/CPshrd-R80/database/postgresql/lib/postgresql/plpgsql.so
#18 0x4db77ed4 in plpgsql_call_handler () from /opt/CPshrd-R80/database/postgresql/lib/postgresql/plpgsql.so
#19 0x081d193f in ExecMakeFunctionResult ()
#20 0x081ce2f5 in ExecProject ()
#21 0x081e563d in ExecResult ()
#22 0x081cdad8 in ExecProcNode ()
#23 0x081ccd71 in standard_ExecutorRun ()
#24 0xf78c5cf9 in pgss_ExecutorRun () from /opt/CPshrd- R80/database/postgresql/lib/postgresql/pg_stat_statements.so
#25 0x081ee9d5 in _SPI_execute_plan ()
#26 0x081eed1a in SPI_execute_plan_with_paramlist ()
#27 0x4db7d69c in exec_run_select () from /opt/CPshrd-R80/database/postgresql/lib/postgresql/plpgsql.so
#28 0x4db80b2a in exec_stmt_perform () from /opt/CPshrd-R80/database/postgresql/lib/postgresql/plpgsql.so
#29 0x4db81861 in exec_stmt () from /opt/CPshrd-R80/database/postgresql/lib/postgresql/plpgsql.so
#30 0x4db825f3 in exec_stmts () from /opt/CPshrd-R80/database/postgresql/lib/postgresql/plpgsql.so
#31 0x4db81279 in exec_stmt_block () from /opt/CPshrd-R80/database/postgresql/lib/postgresql/plpgsql.so
#32 0x4db8454b in plpgsql_exec_function () from /opt/CPshrd-R80/database/postgresql/lib/postgresql/plpgsql.so
#33 0x4db77ed4 in plpgsql_call_handler () from /opt/CPshrd-R80/database/postgresql/lib/postgresql/plpgsql.so
#34 0x081d3b49 in ExecMakeTableFunctionResult ()
#35 0x081e4f74 in FunctionNext ()
#36 0x081d520b in ExecScan ()
#37 0x081e4ef1 in ExecFunctionScan ()
#38 0x081cdb70 in ExecProcNode ()
#39 0x081ccd71 in standard_ExecutorRun ()
#40 0xf78c5cf9 in pgss_ExecutorRun () from /opt/CPshrd- R80/database/postgresql/lib/postgresql/pg_stat_statements.so
#41 0x082a816e in PortalRunSelect ()
#42 0x082a95a8 in PortalRun ()
#43 0x082a67ed in PostgresMain ()
#44 0x08260dfa in ServerLoop ()
#45 0x08261ca7 in PostmasterMain ()
答案 0 :(得分:1)
就我而言,问题是存储过程创建了临时表并用数据填充它们 在填充完成后添加ANALYZE命令后,它现在可以在所有场景中快速运行。 我想数据库关于何时通过autovacuum守护进程收集统计数据的决定不能依赖于您在使用临时表后立即更改表和查询的情况。