2013-10-01 5 views
2

В течение длительного времени я использовал предложение EXISTS, чтобы определить, существует ли хотя бы одна запись в данной таблице для данного условия. , например, - если бы я хотел, чтобы увидеть, если работник по LastName = «кузнец» существует в таблице «сотрудника», я использовал следующий запросПредложение 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 имеет более высокую производительность, чем при использовании EXISTS положение, как показано ниже

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

Это верный? Может кто-то подтвердить это.

Заранее спасибо

ответ

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

Были похож вопрос о StackOverflow.

Здесь Адам 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

Однако, я пытался как на без индекса таблицы и стоимость СУЩЕСТВУЕТ подход немного выше:

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

Спасибо вам (Stephen and Przemyslaw)! – user2836468

+0

Hi Przemyslaw - Я просто прочитал сообщение от Адама Муша. В соответствии с его постом - нет существенной разницы, если колонка индексируется. – user2836468

+0

Прошу прощения - я попал по ошибке. – user2836468

Смежные вопросы