2013-10-01 142 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