在oracle中,显式游标是否将整个查询结果加载到内存中?

时间:2010-03-10 16:18:05

标签: sql oracle plsql cursors

我有一张大约10亿行的表。我是唯一的用户,因此没有锁等争用。 我注意到当我运行这样的东西时:

DECLARE   
  CURSOR cur IS SELECT col FROM table where rownum < N; 
BEGIN
  OPEN cur;
  LOOP
    dbms_output.put_line("blah")
  END LOOP;
  CLOSE cur;
END;

在我点击输入的时间与输出开始​​流入的时间之间存在滞后。如果N很小,那么它是无关紧要的。对于大N(或没有WHERE子句),这种滞后大约是几小时。

我是oracle的新手,你可以告诉我,我认为游标只是在表中保留一个指针,它们会在循环的每次迭代中更新。所以我没想到滞后与执行迭代的表的大小成比例。这是错的吗?游标在迭代之前加载整个查询结果吗?

有没有办法在没有初始开销的情况下逐行迭代表?

2 个答案:

答案 0 :(得分:9)

您看到的是,在程序完成之前,DBMS_OUTPUT.PUT_LINE的输出不会显示。它没有告诉您查询返回第一行的速度。 (我假设你打算在你的例子中实际获取数据)。

您可以通过多种方式监控会话,其中一种方式如下:

DECLARE   
  CURSOR cur IS SELECT col FROM table; 
  l_col table.col%ROWTYPE;
BEGIN
  OPEN cur;
  LOOP
    FETCH cur INTO l_col;
    EXIT WHEN cur%NOTFOUND;
    dbms_application_info.set_module('TEST',l_col);
  END LOOP;
  CLOSE cur;
END;

当它正在运行时,从另一个会话运行:

select action from v$session where module='TEST';

当光标获取行时,您将看到ACTION的值不断变化。

答案 1 :(得分:0)

我还想监视v $ session_longops,以确定Oracle优化器认为“长操作”的操作:

选择消息,time_remaining 来自v $ session_longops 其中time_remaining&gt; 0;