• 在循环中进行提交的测试


        Oracle版本中,如果commit,那么后台的LGWR进程一定会将内存中的redo数据写入
    online redo log文件中,然后再将控制权返回给用户(当然,其实这段也可能不是磁
    盘操作,而是写入到磁盘缓冲中)。如果应用中有过于频繁的用户commit,那么可能
    会产生明显的log file sync的等待事件。

    在loop中提交可能带来的问题:
        性能降低
        当undo比较小的时候,可能出现ora-01555(单次可能发生ora-30036)
        如果失败,数据不一致(一些修改commit了,一些没有)   


    DROP TABLE t PURGE;
    DROP TABLE t1 PURGE;
    CREATE TABLE t AS SELECT * FROM all_objects;
    CREATE TABLE t1 (i int,x NUMBER);
    --BEGIN dbms_stats.gather_table_stats(USER,'T');END;

    SELECT i, count(i),AVG(x) FROM t1 GROUP BY i ORDER BY 3;

    -----------------------------------------------------
    DECLARE
    v_cnt1 NUMBER;
    v_cnt2 NUMBER;
    v_cnt3 NUMBER;
    TYPE ridarr IS TABLE OF ROWID;
    TYPE narr IS TABLE OF t.object_name%TYPE;
    CURSOR c IS
    SELECT ROWID rid, object_name FROM t;
    lrid ridarr;
    lname narr;
    BEGIN
    v_cnt1 := dbms_utility.get_time;
    UPDATE t SET t.object_name = lower(t.object_name);
    COMMIT;
    v_cnt2 := dbms_utility.get_time;
    INSERT INTO t1(i, x) VALUES(1,v_cnt2-v_cnt1);
    COMMIT;

    v_cnt3 := 0;
    v_cnt1 := dbms_utility.get_time;
    FOR x IN (SELECT ROWID rid, object_name oname FROM t) LOOP
    UPDATE t SET t.object_name = lower(x.oname) WHERE t.ROWID = x.rid;
    v_cnt3 := v_cnt3 + 1;
    IF v_cnt3 >= 100 THEN
    COMMIT;
    v_cnt3 := 0;
    END IF;
    END LOOP;
    v_cnt2 := dbms_utility.get_time;
    INSERT INTO t1(i, x) VALUES(2,v_cnt2-v_cnt1);
    COMMIT;

    v_cnt1 := dbms_utility.get_time;
    FOR x IN (SELECT ROWID rid, object_name oname, ROWNUM rn FROM t) LOOP
    UPDATE t SET t.object_name = lower(x.oname) WHERE t.ROWID = x.rid;
    IF MOD(x.rn, 100) = 0 THEN
    COMMIT;
    END IF;
    END LOOP;
    v_cnt2 := dbms_utility.get_time;
    INSERT INTO t1(i, x) VALUES(3,v_cnt2-v_cnt1);
    COMMIT;

    v_cnt1 := dbms_utility.get_time;
    OPEN c;
    LOOP
    FETCH c BULK COLLECT
    INTO lrid, lname LIMIT 100;
    FORALL i IN 1 .. lrid.COUNT
    UPDATE t SET t.object_name = lname(i) WHERE ROWID = lrid(i);
    COMMIT;
    EXIT WHEN c%NOTFOUND;
    END LOOP;
    CLOSE c;
    v_cnt2 := dbms_utility.get_time;
    INSERT INTO t1(i, x) VALUES(4,v_cnt2-v_cnt1);
    COMMIT;

    END;
    /



  • 相关阅读:
    数组的学习(一)
    Servlet是线程安全吗?
    MySql用户管理:添加用户、授权、删除用户
    泛型(二)
    泛型(一)
    Spring MVC
    spring框架
    mybatis基础
    Hibernate 基础
    Java局部类
  • 原文地址:https://www.cnblogs.com/wait4friend/p/2345510.html
Copyright © 2020-2023  润新知