从select查询中拆分数据并提交到临时表中

时间:2014-03-06 16:30:47

标签: sql oracle

我有一个场景,我正在创建一个临时表,其中包含来自select语句的数据。我的问题是当来自select查询的数据很大时,我遇到的内存问题不足导致我的查询无法给出结果。

我想知道是否有办法将一大块数据(比如每1000行)提交到临时表中,然后再转到下一个。

Eg:
CREATE TABLE NEW_TABLE AS
   SELECT [ column1, column2...columnN ]
   FROM EXISTING_TABLE
   [ WHERE ] <ALL CONDITIONS>

现在让我们假设内部选择返回100行。我不希望所有100行一次插入NEW_TABLE。我想分开这个。我该如何有效地做到这一点?

2 个答案:

答案 0 :(得分:0)

如果您创建临时表,为什么不将表创建为 GLOBAL TEMPORARY TABLE ,这样? :

CREATE GLOBAL TEMPORARY TABLE NEW_TABLE AS
SELECT [ column1, column2...columnN ]
FROM EXISTING_TABLE
[ WHERE ] <ALL CONDITIONS>
ON COMMIT DELETE ROWS;

由于“重做生成减少,因此根据定义,它们不进行日志记录。”(http://psoug.org/reference/gtt.html

阐述我写的内容:

“重做记录缓存在 重做日志中的循环时尚 SGA的缓冲区(参见“Oracle如何 数据库写入重做日志“) 并写入重做之一 日志编写器(LGWR)的日志文件 数据库后台进程。“ - docs.oracle.com/cd/B28359_01/server.111/b28310/onlineredo001.htm

使用global temporary可以避免冗余内存成本。我认为你不关心安全临时数据。除了Global Temporary Table,默认值被写入临时表空间,该表空间针对瞬态数据的存储进行了优化。

“当Oracle需要将数据存储在全局临时表中或为散列连接构建哈希表时,Oracle还会在内存中启动操作,并在所涉及的数据量足够小的情况下完成任务而无需写入磁盘。虽然填充全局临时表或构建哈希不是排序操作,但我们将在本文中将所有这些活动混为一谈,因为它们以类似的方式由Oracle处理。

如果某个操作占用了一定量的内存,那么Oracle会将操作分成较小的操作,每个操作都可以在内存中执行。部分结果将在临时表空间中写入磁盘。“

基于:    - 你使用的是除默认进程内存(sga,undo)之外的其他内存区域,在你的情况下看起来很小    - 当内存大小不足时 - &gt; oracle会将数据写入磁盘

答案 1 :(得分:0)

行。我想我有一个临时解决方案/解决我的问题:这样的事情:

DECLARE
    counter  number (6) := 1;
    cursor c1 is
        <select query>

         type t__data is table of c1%rowtype index by inary_integer;
         t_data t__data;

begin

   open c1;
   loop
      fetch c1 bulk collect into t_data; 
      exit when t_data.count = 0;

      for idx in t_data.first .. t_data.last loop

        insert into TEMP_ONE1 (x,y)
            values (t_data(idx).x, t_data(idx).y);
            counter := counter + 1;

         if  counter = 10000
         then
          counter := 0;
          commit;
         end if;

      end loop;

   end loop;
   close c1;

end;

您认为这是解决问题的好方法吗? (我运行查询以获取一小部分数据,但确实有效)