Sql Oracle EXISTS子句Vs ROWNUM=1
很长一段时间以来,我一直在使用Sql Oracle EXISTS子句Vs ROWNUM=1,sql,oracle,Sql,Oracle,很长一段时间以来,我一直在使用EXISTS子句来确定给定条件下给定表中是否至少存在一条记录。 例如,如果我想查看“employee”表中是否存在lastname='smith'的员工,我使用以下查询 select 1 into v_exists_flag from dual where exists (select 1 from employee where lastname = 'smith'
EXISTS
子句来确定给定条件下给定表中是否至少存在一条记录。
例如,如果我想查看“employee”表中是否存在lastname='smith'的员工,我使用以下查询
select 1
into v_exists_flag
from dual
where exists (select 1
from employee
where lastname = 'smith'
)
这肯定比使用count(*)子句更有效
如果v_计数>0,则
但是,最近有人提到使用ROWNUM=1比使用EXISTS子句具有更好的性能,如下所示
select 1
into v_count
from employee
where lastname = 'smith'
and rownum = 1
这是正确的吗?有人能证实这一点吗
提前感谢在启用自动跟踪的情况下尝试这两个选项,看看哪一个选项的一致性越差。我认为它们的性能大致相同,但对我来说,rownum示例更容易阅读 例如:
关于stackoverflow也有类似的问题 Adam Musch在这里指出,没有真正的区别: 下面是关于rownum=1性能的另一个主题: 但是,我在未索引的表上尝试了这两种方法,EXISTS方法的成本略高: 显然,更高的计划是由于额外需要双重呼叫 例如:
CREATE TABLE rownum_test (x)
AS SELECT rownum FROM all_objects;
DECLARE
v_exists NUMBER;
BEGIN
FOR v_i IN 1..34050 LOOP
SELECT 1
INTO v_exists
FROM dual
WHERE EXISTS (SELECT 1 FROM rownum_test WHERE x = v_i);
END LOOP;
END; -- 13,2 seconds
DECLARE
v_exists NUMBER;
BEGIN
FOR v_i IN 1..34050 LOOP
SELECT 1
INTO v_exists
FROM rownum_test
WHERE x = v_i AND rownum = 1;
END LOOP;
END; -- 13,3 seconds
另一方面,测试表明ROWNUM方法稍微慢一点——但可能是我的简单测试数据不够好
在Oracle 11G R2上测试。谢谢你们(Stephen和Przemyslaw)!嗨,普泽米斯劳-我刚刚读了亚当·马斯克的帖子。根据他的帖子-如果该列被索引,则没有显著差异。很抱歉-我错误地点击了send。继续上一条评论-如果该列被索引,则看起来他建议使用EXISTS子句。您的意思是当该列未被索引时;)(亚当·马斯克就是这么写的)。我想这应该在不同的Oracle版本和小型/中型/大型表上进行检查,包括索引和未索引的表,并比较Stephen ODonnell在其文章中提供的统计数据。
SQL> create table t1 as select object_name from all_objects;
Table created.
SQL> create index t1_idx1 on t1 (object_name);
Index created.
SQL> set autot on
SQL> select 1 from t1 where object_name = 'TOP_N' and rownum = 1;
1
----------
1
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
2 consistent gets
0 physical reads
0 redo size
519 bytes sent via SQL*Net to client
523 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> select 1 from dual where exists (select object_name from t1 where object_name = 'TOP_N');
1
----------
1
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
2 consistent gets
0 physical reads
0 redo size
519 bytes sent via SQL*Net to client
523 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
CREATE TABLE rownum_test (x)
AS SELECT rownum FROM all_objects;
DECLARE
v_exists NUMBER;
BEGIN
FOR v_i IN 1..34050 LOOP
SELECT 1
INTO v_exists
FROM dual
WHERE EXISTS (SELECT 1 FROM rownum_test WHERE x = v_i);
END LOOP;
END; -- 13,2 seconds
DECLARE
v_exists NUMBER;
BEGIN
FOR v_i IN 1..34050 LOOP
SELECT 1
INTO v_exists
FROM rownum_test
WHERE x = v_i AND rownum = 1;
END LOOP;
END; -- 13,3 seconds