【问题标题】:Oracle get UNIQUE constraint violation error too lateOracle 得到 UNIQUE 约束违反错误太晚了
【发布时间】:2021-12-14 04:49:51
【问题描述】:

我应该如何检查为什么 Oracle 服务器需要超过 20 秒才能返回特定数据的 UNIQUE 约束违规错误?

我们的一个进程一天处理超过 30000 个数据,多进程,有时会在 1 秒内出现 UNIQUE 约束违规错误

但返回特定数据的UNIQUE 约束违规错误需要超过 20 秒。

查询如下。 (只修改表名)

MERGE  
INTO  TableA S
USING (
SELECT NVL(:sccm_cd , ' ') SCCM_CD
 , NVL(:oder_dt , ' ') ODER_DT
 , NVL(:mrkt_dstn_cd, ' ') MRKT_DSTN_CD
 , NVL(:oder_no , ' ') ODER_NO
 , NVL(:cncd_unpr , 0) CNCD_UNPR
 , B.SLBY_FEE_GRD_CD
 , B.ACCT_MNGR_EMPL_NO
 , C.AO_FEE_GRD_CD
  FROM DUAL A
 , TableB B
 , TableC C
 WHERE 1 = 1
   AND B.SCCM_CD = :sccm_cd
   AND B.ACNO = :acno
   AND C.SCCM_CD(+) = B.SCCM_CD
   AND C.EMPL_NO(+) = B.ACCT_MNGR_EMPL_NO 
      ) T
ON (     S.sccm_cd       = T.sccm_cd
     AND S.oder_dt         = T.oder_dt
     AND S.mrkt_dstn_cd = T.mrkt_dstn_cd 
     AND S.oder_no        = T.oder_no
     AND S.cncd_unpr     = T.cncd_unpr 
     )
WHEN MATCHED THEN
     UPDATE 
     SET S.cncd_qty       = S.cncd_qty       + NVL(:cncd_qty     ,0)
           , S.slby_fee        = S.slby_fee        + NVL(:slby_fee      ,0)
           , S.slby_fee_srtx = S.slby_fee_srtx + NVL(:slby_fee_srtx,0)
           , S.idx_fee_amt   = S.idx_fee_amt   + NVL(:idx_fee_amt ,0)
           , S.cltr_fee          = S.cltr_fee         + NVL(:cltr_fee        ,0)
           , S.trtx                = S.trtx               + NVL(:trtx             ,0)     
           , S.otc_fee        = S.otc_fee               + NVL(:otc_fee             ,0)     
           , S.wht_fee       = S.wht_fee               + NVL(:wht_fee             ,0)                                   
WHEN NOT MATCHED THEN
     INSERT (
              sccm_cd
        , oder_dt
        , mrkt_dstn_cd
        , oder_no
        , cncd_unpr
        , acno
        , item_cd
        , slby_dstn_cd
        , md_dstn_cd
        , cncd_qty
        , stlm_dt
        , trtx_txtn_dstn_cd
        , proc_cmpl_dstn_cd
        , item_dstn_cd
        , slby_fee_grd_cd
        , slby_fee
        , slby_fee_srtx
        , idx_fee_amt
        , cltr_fee
        , trtx     
        , wht_fee        
        , otc_fee
            , acct_mngr_empl_no
            , ao_fee_grd_cd
            
        )
        VALUES
        (     T.sccm_cd
            , T.oder_dt
            , T.mrkt_dstn_cd
            , T.oder_no
            , T.cncd_unpr
            , :acno
            , :item_cd
            , :slby_dstn_cd
            , :md_dstn_cd
            , NVL(:cncd_qty     ,0) 
            , DECODE(:mrkt_dstn_cd, 'TN', T.oder_dt, :stlm_dt)
            , :trtx_txtn_dstn_cd
            , '0'
            , :item_dstn_cd
            , NVL(:slby_fee_grd_cd, T.SLBY_FEE_GRD_CD)
            , NVL(:slby_fee        ,0)
            , NVL(:slby_fee_srtx ,0)
            , NVL(:idx_fee_amt   ,0)
            , NVL(:cltr_fee          ,0)
            , NVL(:trtx                ,0)
            , NVL(:wht_fee     , 0)                        
            , NVL(:otc_fee    , 0)
            , T.acct_mngr_empl_no
            , T.ao_fee_grd_cd
            
          )

【问题讨论】:

  • 我不确定我是否理解“1 秒”和“20 秒”在这里测量的内容。客户端向数据库发送merge 语句到数据库响应唯一约束违规错误之间的时间?如果是这样,那么在该时间段内会话正在等待什么?我的猜测是会话被阻塞,等待另一个会话锁定了它尝试更新的行,并且另一个会话需要 20 秒才能提交或回滚其更改。
  • 当它需要更长的时间时,我猜你有一个会话链,每个会话都被另一个阻止(即 A 被 B 阻止,C 被 D 阻止)需要更多时间来解决。
  • @JustinCave 啊....我知道了,我会根据你的建议深入检查:) 谢谢

标签: sql performance oracle11g


【解决方案1】:

可能有多种原因。我将在此处列出导致此行为的一些可能原因。

并发问题

您的insert 可能正在等待其他操作,例如其他插入或更新或删除。

网络问题

可能由于某种原因,您的网络被请求淹没了,或者,如果服务器是远程的,这也可能是互联网速度问题。

服务器负载

服务器可能会因为大量工作而不堪重负。

慢查询

您在insert 命令中使用的select 也可能非常慢。测试它的速度是有意义的。此外,测试insert 的速度也是有意义的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-17
    • 2015-05-16
    • 1970-01-01
    相关资源
    最近更新 更多