• oracle 大批量数据更新


    现场如下:

    有表

    A(ID,CODE,C....C1,C2,C3),300W数据。C1,C2,C3是空的

    B(ID,CODE,C.....C1,C2,C3),1万数据

    现在要将A表中的C1到C3几个字段通过关联查询B表更新。

    自己尝试了几个方案:不仅速度慢,还容易报错:ORA-01555: 快照过旧: 回退段号 6352 (名称为 "_SYSSMU6352_1445123658$") 过小

    方案1:直接关联查询更新:

    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:

    用指针,

    又分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效率上会快很多。

  • 相关阅读:
    java知识点-高级
    Java中高级面试题
    项目基础
    TFS Build Error: CSC : fatal error CS0042: Unexpected error creating debug information file 'xxxx.PDB'
    System.FormatException: Index (zero based) must be greater than or equal to zero and less than the size of the argument list
    (C#) System.BadImageFormatException: An attempt was made to load a program with an incorrect format.
    (C#) 引用工程中发现有黄色叹号
    (C#).NET 2.0 ~ 4.0 OS requirements.
    (WCF) WCF and Service Debug
    (WCF) WCF Service Hosting.
  • 原文地址:https://www.cnblogs.com/andy-wcl/p/3271910.html
Copyright © 2020-2023  润新知