2013-10-01 3 views
2

Pendant longtemps, j'ai utilisé la clause EXISTS pour déterminer si au moins un enregistrement existe dans une table donnée pour une condition donnée. par exemple - si je voulais voir si un employé par lastname = « Smith » existe dans la table « employé », j'ai utilisé la requête suivanteClause Oracle EXISTS Vs ROWNUM = 1

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

Ceci est nettement plus efficace que d'utiliser le compte (*) clause.

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

si v_count> 0 alors ....

Mais, récemment quelqu'un a dit que l'utilisation ROWNUM = 1 a de meilleures performances que d'utiliser la clause EXISTS comme indiqué ci-dessous

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

Est-ce correct? Quelqu'un peut-il confirmer cela?

Merci à l'avance

Répondre

3

Essayez les deux options avec autotrace activé et voir ceux qui se charge du moins cohérente obtient. Je pense qu'ils vont tous les deux faire à peu près la même chose, mais pour moi, l'exemple de rownum est plus facile à lire.

Par exemple:

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

Il y avait sur stackoverflow question similaire.

Ici Adam Musch déclare qu'il n'y a pas de différence réelle: The fastest way to check if some records in a database table?

Voici un autre sujet à propos rownum = 1 performance: Under what conditions does ROWNUM=1 significantly increase performance in an "exists" syle query

Cependant, j'ai essayé à la fois sur une table non indexée et le coût de la EXISTE approche est légèrement plus élevé:

ROWNUM approach plan EXISTS approach plan Il est évident que le plan est plus élevé en raison de la nécessité supplémentaire dU Appel AL.

Exemple:

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 

Le test, d'autre part, montre que l'approche ROWNUM est légèrement plus lente - mais il se peut que mon simple, les données de test n'est pas assez bon.

Test sur Oracle 11G R2.

+0

Merci à vous deux (Stephen et Przemyslaw)! – user2836468

+0

Salut Przemyslaw - Je viens de lire l'article d'Adam Musch. Accoridng à son poste - aucune différence significative, si la colonne est indexée. – user2836468

+0

Je suis désolé - je l'ai envoyé par erreur. – user2836468