2015-10-18 35 views
-1

我有一些應用程序打開一個事務並運行存儲過程。 在存儲過程中有一些「insert into X select Y」語句。 在某些情況下,存儲過程需要花費一個多小時才能完成,同時佔用100%,大部分時間不執行IO操作。Postgres:瞭解爲什麼查詢需要從應用程序這麼久,但從psql工作正常

當我嘗試從psql在相同的數據庫/數據上運行存儲過程時,需要一分鐘。

通常我使用解釋分析來理解瓶頸,但是因爲它按照預期從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

你有沒有檢查它是否可能正在等待鎖? https://wiki.postgresql.org/wiki/Lock_Monitoring –

+0

檢查,沒有鎖。我認爲如果它卡在一個鎖上,它不會佔用100%的CPU。 –

+1

您可以安裝自動解釋模塊:http://www.postgresql.org/docs/current/static/auto-explain.html我也認爲,您應該將其發佈到Postgres郵件列表中:http:// www .postgresql.org/list/ –

回答

1

在我的情況下,問題是,在存儲過程中創建臨時表,並用數據填充它們。
填充後添加ANALYZE命令後,它現在在所有情況下快速運行。 我猜想數據庫關於何時通過autovacuum守護進程收集統計數據的決定不能取決於在您明顯改變表格和查詢之後或使用臨時表格的情況。

+1

[來自手冊](http://www.postgresql.org/docs/current/static/routine -vacuuming.html#AUTOVACUUM):「*臨時表不能被autovacuum訪問,因此,適當的真空和分析操作應該通過會話SQL命令執行*」 –

相關問題