3

私は長い間、このEXISTS句を使用して、特定の条件で特定のテーブルに少なくとも 1 つのレコードが存在するかどうかを判断してきました。たとえば、lastname = 'smith' の従業員が「employee」テーブルに存在するかどうかを確認したい場合は、次のクエリを使用しました。

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

これは、count(*) 句を使用するよりも確実に効率的です。

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

v_count > 0 の場合....

しかし、最近誰かが、以下に示すように EXISTS 句を使用するよりも ROWNUM = 1 を使用する方がパフォーマンスが優れていると述べました。

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

これは正しいです?誰かがこれを確認できますか。

前もって感謝します

4

2 に答える 2

3

autotrace を有効にして 2 つのオプションを試してみて、一貫性のある取得が少ないオプションを確認してください。どちらもほぼ同じように機能すると思いますが、私にとっては、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
于 2013-10-01T21:07:14.463 に答える
1

stackoverflow にも同様の質問がありました。

ここで Adam Musch は、本当の違いはないと述べてい ます。

rownum = 1 のパフォーマンスに関する別のトピックを次に 示します。「存在する」スタイルのクエリで ROWNUM=1 がパフォーマンスを大幅に向上させる条件は何ですか

ただし、インデックスのないテーブルの両方で試してみましたが、EXISTS アプローチのコストはわずかに高くなります。

ROWNUMアプローチプラン EXISTS アプローチプラン 明らかに、より高い計画は、DUAL 呼び出しの追加の必要性によるものです。

例:

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 でのテスト。

于 2013-10-01T21:10:13.910 に答える