0

我有一个大约有 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;

在我按 enter 的时间和输出开始流入的时间之间存在延迟。如果 N 很小,那么它是微不足道的。对于大 N(或没有 WHERE 子句),此滞后时间约为数小时。

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

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

4

2 回答 2

9

What you are seeing is that the output from DBMS_OUTPUT.PUT_LINE is not displayed until the program has finished. It doesn't tell you anything about how fast the query returned a first row. (I assume you intended to actually fetch data in your example).

There are many ways you can monitor a session, one is like this:

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;

While that is running, from another session run:

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

You will see that the value of ACTION keeps changing as the cursor fetches rows.

于 2010-03-10T17:18:49.930 回答
0

我还喜欢监视 v$session_longops 中被 Oracle 优化器视为“长操作”的操作:

从 v$session_longops 中选择消息 time_remaining,其中 time_remaining > 0;

于 2010-03-17T22:03:53.013 回答