什么是批量收集的最大限制在嵌套表中(我使用它为1000万条记录)

时间:2018-05-02 14:50:24

标签: plsql oracle11g bulk-collect

我使用嵌套表来收集表的数据。并使用此数据插入另一个表中。下面是我正在使用的代码。我对批量收集的容量感到好奇。

$('#messages').append($('<li>').text(msg.name + ": " + msg.message));

1 个答案:

答案 0 :(得分:3)

简短的回答是没有限制(除了可用的系统内存),但我认为你问的是错误的问题。正确的问题是:什么是用于散装绑定的好尺寸?确实没有确切的数字,但有几点需要考虑:

  • 您正在使用批量绑定来减少上下文切换(从处理程序的PL / SQL引擎到插入行和返回的数据库引擎)
  • 您的收藏越大,您的节目消耗的内存就越多
  • 最终你会使集合变得如此之大,以至于你的程序因为上下文切换而不会“慢”,但是由于其他原因(CPU,可用内存,磁盘争用等)

我的个人规则是大约100到250行是一个很好的尺寸。您可以自己测试一下,看看因为集合获得非常大的性能实际上是WORSE。你想选择一个表现良好且使用最少内存的数字:我的下面的测试显示即使50也足够好。

DROP TABLE t;
DROP TABLE v;

CREATE TABLE t AS
SELECT * FROM all_objects
CROSS JOIN (SELECT LEVEL FROM dual CONNECT BY LEVEL <= 10);

SELECT COUNT(*) FROM t;
-- 770260

CREATE TABLE v AS SELECT * FROM t WHERE 0 = 1;

DECLARE
  TYPE t_tab IS TABLE OF t%ROWTYPE;
  x_tab t_tab;

  CURSOR c IS
    SELECT *
      FROM t;

  c_bulk_size INTEGER := 50000;
  v_start     TIMESTAMP(9) := current_timestamp;
BEGIN
  OPEN c;

  LOOP
    FETCH c BULK COLLECT
      INTO x_tab LIMIT c_bulk_size;

    IF x_tab.count > 0 THEN
      FORALL i IN x_tab.first .. x_tab.last
        INSERT INTO v
        VALUES x_tab
          (i);
    END IF;

    EXIT WHEN x_tab.count < c_bulk_size;
  END LOOP;

  dbms_output.put_line((current_timestamp - v_start) || ' size ' ||
                       c_bulk_size);

  CLOSE c;

  ROLLBACK;
END;
/
-- +000000000 00:00:11.696873000 size 50
-- +000000000 00:00:12.692300000 size 50
-- +000000000 00:00:11.634849000 size 50

-- +000000000 00:00:12.770239000 size 100
-- +000000000 00:00:11.268332000 size 100
-- +000000000 00:00:11.793120000 size 100

-- +000000000 00:00:11.400098000 size 250
-- +000000000 00:00:10.625674000 size 250
-- +000000000 00:00:11.783102000 size 250

-- +000000000 00:00:09.490830000 size 500
-- +000000000 00:00:10.411275000 size 500
-- +000000000 00:00:11.713433000 size 500

-- +000000000 00:00:09.140556000 size 1000
-- +000000000 00:00:12.459841000 size 1000
-- +000000000 00:00:09.132134000 size 1000

-- +000000000 00:00:10.188990000 size 10000
-- +000000000 00:00:09.758166000 size 10000
-- +000000000 00:00:10.685548000 size 10000

-- +000000000 00:00:19.255858000 size 50000
-- +000000000 00:00:20.929404000 size 50000
-- +000000000 00:00:24.243393000 size 50000

我希望这会有所帮助。如果您搜索批量收集限制,互联网上有很多关于此的文章。 AskTom上有一对值得一读。