我有一张大约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的新手,你可以告诉我,我认为游标只是在表中保留一个指针,它们会在循环的每次迭代中更新。所以我没想到滞后与执行迭代的表的大小成比例。这是错的吗?游标在迭代之前加载整个查询结果吗?
有没有办法在没有初始开销的情况下逐行迭代表?
答案 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;