現場以下: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效率上會快不少。