请第一排 - 哪一个更好


LV_id number;
Cursor CR_test Is
  select t.id
  from table1 t
  where t.foo = p_foo
  order by t.creation_date; 
Open CR_test;
Fetch CR_test
 Into LV_id;
Close CR_test;

或者这个:

select x.id
from(select t.id
     from table1 t
     where t.foo=p_foo
     order by t.creation_date) x
where rownum = 1

以上两者的结果相似,但我需要知道哪一个更有效!

这是Tom Kyte的口头禅:

如果可能的话,您应该在单个 SQL 语句中执行此操作。
如果您不能在单个SQL语句中执行此操作,则在PL/SQL中执行此操作。
如果无法在 PL/SQL 中执行此操作,请尝试使用 Java 存储过程。
如果无法在 Java 中执行此操作,请在 C 外部过程中执行此操作。
如果你不能在 C 外部例程中做到这一点,你可能要认真考虑为什么你需要这样做......

http://tkyte.blogspot.com/2006/10/slow-by-slow.html

在这种情况下,找出答案的最简单方法是测试您的查询。

请务必自己测试,表中的索引和数据可能会对表产生不同的结果。

没有任何索引,看起来有一种更好的方法使用分析函数DENSE_RANK:

SELECT MIN(id) KEEP (DENSE_RANK FIRST ORDER BY creation_date)
INTO lv_id
FROM table1
WHERE foo = p_foo;

我使用以下代码来测试查询所消耗的时间(多次执行此块,结果可能会有所不同(:

DECLARE
  p_foo  table1.foo%TYPE := 'A';
  lv_id  table1.id%TYPE;
  t      TIMESTAMP := SYSTIMESTAMP;
BEGIN
  FOR i IN 1 .. 100 LOOP
    -- Query here
  END LOOP;
  dbms_output.put_line(SYSTIMESTAMP - t);
END;

结果:

  1. 使用光标,获取第一行:
    2.241 秒

  2. 将查询与ROWNUM一起使用:
    1.483 秒

  3. 使用DENSE_RANK
    1.168 秒

相关内容

最新更新