You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python使用cx_Oracle执行Oracle MERGE语句长时间无响应如何解决?

cx_Oracle执行MERGE语句无响应排查方案

1. 优先排查锁阻塞

绝大多数跨客户端执行SQL卡住的场景都是锁冲突导致:

  • 用DBA权限账号登录Oracle执行以下SQL,查询是否存在阻塞会话:
SELECT
  s1.username || '@' || s1.machine || ' (SID=' || s1.sid || ') 阻塞 ' || s2.username || '@' || s2.machine || ' (SID=' || s2.sid || ')' AS block_relation
FROM v$lock l1
JOIN v$session s1 ON l1.sid = s1.sid
JOIN v$lock l2 ON l1.id1 = l2.id1 AND l1.id2 = l2.id2
JOIN v$session s2 ON l2.sid = s2.sid
WHERE l1.block = 1 AND l2.request > 0;
  • 如果查询到对应Python会话被阻塞,确认阻塞会话的操作是否可以终止,提交/回滚阻塞会话的事务,或者执行ALTER SYSTEM KILL SESSION 'SID,SERIAL#'清理异常阻塞会话即可。

2. 验证执行计划一致性

不同客户端的会话参数差异可能导致执行计划不同,出现SQL Developer执行快、Python执行慢的情况:

  • 先查询Python会话对应的SQL_ID:
SELECT sid, serial#, sql_id, status 
FROM v$session 
WHERE username = '你的数据库账号' AND program LIKE '%python%';
  • 用SQL_ID查询实际执行计划:
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('替换为实际SQL_ID', 0, 'ALLSTATS LAST'));
  • 和SQL Developer中执行MERGE的执行计划对比,若存在差异,先更新两张表的统计信息再重试:
EXEC DBMS_STATS.GATHER_TABLE_STATS('ASBODS_SDDM_SCHEMA', 'EULA_DATA');
EXEC DBMS_STATS.GATHER_TABLE_STATS('ASBODS_SDDM_SCHEMA', 'EULA_STG_DATA');

3. 大数据量分批优化

如果EULA_STG_DATA表数据量较大,全量MERGE本身就是长耗时操作:

  • 先在Linux服务器上用sqlplus直接执行相同MERGE语句,确认是否是cx_Oracle层的问题
  • 拆分MERGE逻辑,按MASTER_METER_NBR范围、日期字段等维度拆分SQL,每次处理部分数据,避免单条SQL执行时间过长
  • 可以给cx_Oracle连接添加超时配置(Oracle 18c及以上版本支持),避免进程无限挂起:
con = cx_Oracle.connect('username/pwd@server', encoding="UTF-8", nencoding="UTF-8")
con.call_timeout = 300000 # 单位为毫秒,此处设置5分钟超时

4. 冗余代码优化

你当前代码的finally块中重复执行了con.commit(),属于冗余操作,虽然不影响执行逻辑,但建议删除,避免异常场景下提交脏数据。


内容的提问来源于stack exchange,提问作者William

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.21 09:24:05