For a long time, I have been using the EXISTS
clause to determine if at least one record exists in a given table for a given condition. for example - if I wanted to see if an employee by lastname = 'smith' exists in the "employee" table, I used the following query
select 1
into v_exists_flag
from dual
where exists (select 1
from employee
where lastname = 'smith'
)
This is definitely more efficient than using the count(*) clause.
select count(*)
into v_count
from employee
where lastname = 'smith'
if v_count > 0 then....
But, recently someone mentioned that using ROWNUM = 1 has better performance than using the EXISTS clause as shown below
select 1
into v_count
from employee
where lastname = 'smith'
and rownum = 1
Is this correct? Can someone confirm this.
Thanks in advance
Try the two options out with autotrace enabled and see which ones does the fewer consistent gets. I think they will both perform about the same, but for me, the rownum example is easier to read.
Eg:
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
There were similiar question on stackoverflow.
Here Adam Musch states that there is no real difference: The fastest way to check if some records in a database table?
Here is another topic about rownum = 1 performance: Under what conditions does ROWNUM=1 significantly increase performance in an "exists" syle query
However, I tried both on an unindexed table and the cost of the EXISTS approach is slightly higher:
Obviously the higher plan is due to the additional need for DUAL call.
Example:
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
The test, on the other hand, shows that ROWNUM approach is slightly slower - but it may be that my simple test data is not good enough.
Testing on Oracle 11G R2.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.