oracle 大批量數據更新

 

現場以下:spa

有表指針

A(ID,CODE,C....C1,C2,C3),300W數據。C1,C2,C3是空的code

B(ID,CODE,C.....C1,C2,C3),1萬數據blog

如今要將A表中的C1到C3幾個字段經過關聯查詢B表更新。資源

本身嘗試了幾個方案:不只速度慢,還容易報錯:ORA-01555: 快照過舊: 回退段號 6352 (名稱爲 "_SYSSMU6352_1445123658$") 太小it

 

方案1:直接關聯查詢更新:class

MERGE INTO YTRUT.T_RUT_WAYBILL_SUM A
USING (SELECT K.CODE,
              K.MANAGEMENT_AREA,
              K.REGION_MANAGE,
              K.TRANSPORT_CENTER,
              K.BRANCH,
              K.SUB_DEPARTMENT
         FROM YTMDM.MV_MDM_ORG_RPT K) B
ON (A.ORIG_ORG = B.CODE)
WHEN MATCHED THEN
  UPDATE
     SET A.DEST_MANAGEMENT_AREA  = B.MANAGEMENT_AREA,
         A.DEST_REGION_MANAGE    = B.REGION_MANAGE,
         A.DEST_TRANSPORT_CENTER = B.TRANSPORT_CENTER,
         A.DEST_BRANCH           = B.BRANCH,
         A.DEST_SUB_DEPARTMENT   = B.SUB_DEPARTMENT;
COMMIT;

這樣發現效率太慢,事物太大,========================效率

方案2:date

用指針,select

又分2中狀況:

1是在來源表用CURSOR,

DECLARE
  CURSOR CUR_ORG IS
    SELECT K.CODE,
           K.MANAGEMENT_AREA,
           K.REGION_MANAGE,
           K.TRANSPORT_CENTER,
           K.BRANCH,
           K.SUB_DEPARTMENT
      FROM YTMDM.MV_MDM_ORG_RPT K;
  C_ROW CUR_ORG%ROWTYPE;
BEGIN

  FOR C_ROW IN CUR_ORG LOOP
    UPDATE YTRUT.T_RUT_WAYBILL_SUM A
       SET A.DEST_MANAGEMENT_AREA  = C_ROW.MANAGEMENT_AREA,
           A.DEST_REGION_MANAGE    = C_ROW.REGION_MANAGE,
           A.DEST_TRANSPORT_CENTER = C_ROW.TRANSPORT_CENTER,
           A.DEST_BRANCH           = C_ROW.BRANCH,
           A.DEST_SUB_DEPARTMENT   = C_ROW.SUB_DEPARTMENT
     WHERE A.ORIG_ORG = C_ROW.CODE
       AND A.TARGET_DAY = TRUNC(SYSDATE) - 4;
    COMMIT;
  
    UPDATE YTRUT.T_RUT_WAYBILL_SUM A
       SET A.DEST_MANAGEMENT_AREA  = C_ROW.MANAGEMENT_AREA,
           A.DEST_REGION_MANAGE    = C_ROW.REGION_MANAGE,
           A.DEST_TRANSPORT_CENTER = C_ROW.TRANSPORT_CENTER,
           A.DEST_BRANCH           = C_ROW.BRANCH,
           A.DEST_SUB_DEPARTMENT   = C_ROW.SUB_DEPARTMENT
     WHERE A.DEST_ORG = C_ROW.CODE
       AND A.TARGET_DAY = TRUNC(SYSDATE) - 4;
    COMMIT;
  
  END LOOP;
END;

 

2,是在目標表用CURSOR

DECLARE
  CURSOR CUR_D IS
    SELECT DISTINCT T.DEST_ORG
      FROM YTRUT.T_RUT_WAYBILL_SUM T
     WHERE T.TARGET_DAY = TRUNC(SYSDATE) - 3;
  C_ROW CUR_D%ROWTYPE;
BEGIN
  --目的網點的  
  FOR C_ROW IN CUR_D LOOP
    MERGE INTO YTRUT.T_RUT_WAYBILL_SUM A
    USING (SELECT K.CODE,
                  K.MANAGEMENT_AREA,
                  K.REGION_MANAGE,
                  K.TRANSPORT_CENTER,
                  K.BRANCH,
                  K.SUB_DEPARTMENT
             FROM YTMDM.MV_MDM_ORG_RPT K
            WHERE K.CODE = C_ROW.DEST_ORG) B
    ON (A.DEST_ORG = B.CODE AND A.TARGET_DAY = TRUNC(SYSDATE) - 4)
    WHEN MATCHED THEN
      UPDATE
         SET A.DEST_MANAGEMENT_AREA  = B.MANAGEMENT_AREA,
             A.DEST_REGION_MANAGE    = B.REGION_MANAGE,
             A.DEST_TRANSPORT_CENTER = B.TRANSPORT_CENTER,
             A.DEST_BRANCH           = B.BRANCH,
             A.DEST_SUB_DEPARTMENT   = B.SUB_DEPARTMENT;
    COMMIT;
  END LOOP;
END;

 效率都很慢,

 

方案4:

使用中間表代替,先關聯查詢select將結果集放入中間表,再將原表數據清除,將中間表數據Insert進去

DECLARE
BEGIN
--STEP 1,清空臨時表
  EXECUTE IMMEDIATE 'TRUNCATE TABLE YTRUT.T_RUT_WAYBILL_SUM_WCL';
  --TRUNCATE TABLE T_RUT_WAYBILL_SUM_WCL;
  --CREATE TABLE YTRUT.T_RUT_WAYBILL_SUM_WCL AS SELECT * FROM YTRUT.T_RUT_WAYBILL_SUM WHERE 1 = 2;
--STEP2,像臨時表插入關聯查詢數據
  INSERT INTO YTRUT.T_RUT_WAYBILL_SUM_WCL
    SELECT T.ORIG_ORG,
           T.DEST_ORG,
           T.TOTAL_COUNT,
           T.TOTAL_WEIGHT,
           T.TARGET_DAY,
           T.ORIG_AREA,
           T.DEST_AREA,
           T.ORIG_PROVINCE,
           T.DEST_PROVINCE,
      ......
           T.COUNT_48H,
           T.WEIGHT_48H,
           K1.MANAGEMENT_AREA,
           K1.REGION_MANAGE,
           K1.TRANSPORT_CENTER,
           K1.BRANCH,
           K1.SUB_DEPARTMENT,
           K2.MANAGEMENT_AREA,
           K2.REGION_MANAGE,
           K2.TRANSPORT_CENTER,
           K2.BRANCH,
           K2.SUB_DEPARTMENT
      FROM YTRUT.T_RUT_WAYBILL_SUM T,
           YTMDM.MV_MDM_ORG_RPT    K1,
           YTMDM.MV_MDM_ORG_RPT    K2
     WHERE K1.CODE = T.ORIG_ORG
       AND K2.CODE = T.DEST_ORG
       AND T.TARGET_DAY = TRUNC(SYSDATE) - 2;
       
       commit;
       ----STEP3,將原表數據清除,
       DELETE FROM  YTRUT.T_RUT_WAYBILL_SUM T WHERE T.TARGET_DAY = TRUNC(SYSDATE) -2;
       commit;
       --STEP4,將臨時表數據插入原表
       INSERT INTO YTRUT.T_RUT_WAYBILL_SUM SELECT * FROM YTRUT.T_RUT_WAYBILL_SUM_WCL ;
       commit;
END;

效果槓槓的!速度嗖嗖的!只用了不到半個小時就把幾百萬數據更新好了。

 

 

總結:

此類更新操做

無非是使用 CURSOR,LOOP,等循環批量操做數據,因爲update是比較消耗資源的方法,會有undo和redo操做,所以換用insert效率上會快不少。

相關文章
相關標籤/搜索