2013-10-01 109 views
2

长期以来,我一直在使用EXISTS子句来确定给定条件下给定表中是否至少存在一条记录。 - 例如,如果我想看看是否由姓氏=“史密斯”雇员在“雇员”表存在,我用下面的查询Oracle EXISTS子句Vs ROWNUM = 1

select 1 
    into v_exists_flag 
    from dual 
where exists (select 1 
       from employee 
       where lastname = 'smith' 
      ) 

这比使用次数肯定更有效的是(*)条款。

select count(*) 
    into v_count 
    from employee 
where lastname = 'smith' 

如果v_count> 0,则....

不过,最近有人指出,使用ROWNUM = 1比使用如下图所示

select 1 
    into v_count 
    from employee 
where lastname = 'smith' 
    and rownum = 1 

难道这就是EXISTS子句更好的性能正确?有人可以证实这一点。

在此先感谢

回答

3

尝试两种选择了启用自动跟踪,看看哪些确实较少一致获取。我认为他们两人的表现都差不多,但对我来说,rownum的例子更容易阅读。

如:

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 
1

有计算器上的问题similiar。

这里亚当MUSCH指出,没有实质的区别: The fastest way to check if some records in a database table?

以下是有关的rownum = 1种性能的另一个话题: Under what conditions does ROWNUM=1 significantly increase performance in an "exists" syle query

不过,我想无论在一个没有索引的表和成本EXISTS的办法是略高:

ROWNUM approach plan EXISTS approach plan 显然更高的计划是由于对杜的额外要求AL电话。

例子:

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上​​进行测试。

+0

谢谢你们俩(斯蒂芬和普热米斯瓦夫)! – user2836468

+0

嗨Przemyslaw - 我刚刚读过Adam Musch的文章。按照他的职位 - 如果列被编入索引,则无显着差异。 – user2836468

+0

对不起 - 我误打误打了。 – user2836468