Problem with Top N Query when no rows returned (takes forever)

I have a table with 100 Million rows and I want to get the latest N records using:
SELECT * FROM
(SELECT * FROM tablename WHERE columnA= 'ABC' ORDER BY TIME DESC)
WHERE rownum <= N;
This works fine and is very fast when there are rows with columnA= 'ABC' but when there are no rows with columnA= 'ABC' the query takes forever.
The strange things is that the inner query returns immediately when run on it's own when no rows with columnA= 'ABC' exist e.g.
SELECT * FROM tablename WHERE columnA= 'ABC' ORDER BY TIME DESC
So why does it take for ever for to run:
SELECT * FROM (no rows inner query) WHERE rownum <= N;
I have also tried using:
SELECT * FROM
(SELECT columnA, rank() over(ORDER BY TIME DESC) time_rank
FROM tablename WHERE columnA='ABC')
WHERE time_rank <= N;
which returns instantly when there are now rows but takes much longer than the first query when there are rows.

I cannot see a real difference:With histogram we can see a difference on the elapse when no row returned and into explain plan.
SQL> drop table tablename
  2  /
Table dropped.
Elapsed: 00:00:00.03
SQL>
SQL> create table tablename
  2  as
  3  select sysdate - l time
  4         , decode(trunc(dbms_random.value(1,10)),1,'ABC',2,'DEF',3,'GHI',4,'JKL','MNO') as columnA
  5    from (select level l from dual connect by level <= 1000000)
  6  /
Table created.
Elapsed: 00:01:19.08
SQL>
SQL> select columnA,count(*) from tablename group by columnA
  2  /
COL   COUNT(*)
ABC     110806
DEF     111557
GHI     111409
JKL     111030
MNO     555198
Elapsed: 00:00:05.05
SQL>
SQL> create index i1 on tablename(time)
  2  /
Index created.
Elapsed: 00:00:34.08
SQL>
SQL> create index i2 on tablename(columna)
  2  /
Index created.
Elapsed: 00:00:30.08
SQL>
SQL> exec dbms_stats.gather_table_stats(user,'TABLENAME',cascade=>true)
PL/SQL procedure successfully completed.
Elapsed: 00:01:18.09
SQL>
SQL> set autotrace on explain
SQL> SELECT * FROM
  2  (SELECT * FROM tablename WHERE columnA= 'ABC' ORDER BY TIME DESC)
  3  WHERE rownum <= 10
  4  /
TIME     COL
17/09/06 ABC
12/09/06 ABC
08/09/06 ABC
07/09/06 ABC
25/08/06 ABC
22/08/06 ABC
13/08/06 ABC
08/07/06 ABC
14/06/06 ABC
01/05/06 ABC
10 rows selected.
Elapsed: 00:00:01.04
Execution Plan
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=2364 Card=10 Bytes=120)
   1    0   COUNT (STOPKEY)
   2    1     VIEW (Cost=2364 Card=200000 Bytes=2400000)
   3    2       SORT (ORDER BY STOPKEY) (Cost=2364 Card=200000 Bytes=2400000)
   4    3         TABLE ACCESS (FULL) OF 'TABLENAME' (Cost=552 Card=200000 Bytes=2400000)
SQL>
SQL> SELECT * FROM
  2  (SELECT * FROM tablename WHERE columnA= 'MNO' ORDER BY TIME DESC)
  3  WHERE rownum <= 10
  4  /
TIME     COL
20/09/06 MNO
19/09/06 MNO
16/09/06 MNO
14/09/06 MNO
13/09/06 MNO
10/09/06 MNO
06/09/06 MNO
05/09/06 MNO
03/09/06 MNO
02/09/06 MNO
10 rows selected.
Elapsed: 00:00:02.04
Execution Plan
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=2364 Card=10 Bytes=120)
   1    0   COUNT (STOPKEY)
   2    1     VIEW (Cost=2364 Card=200000 Bytes=2400000)
   3    2       SORT (ORDER BY STOPKEY) (Cost=2364 Card=200000 Bytes=2400000)
   4    3         TABLE ACCESS (FULL) OF 'TABLENAME' (Cost=552 Card=200000 Bytes=2400000)
SQL>
SQL> SELECT * FROM
  2  (SELECT * FROM tablename WHERE columnA= 'PQR' ORDER BY TIME DESC)
  3  WHERE rownum <= 10
  4  /
no rows selected
Elapsed: 00:00:01.01
Execution Plan
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=2364 Card=10 Bytes=120)
   1    0   COUNT (STOPKEY)
   2    1     VIEW (Cost=2364 Card=200000 Bytes=2400000)
   3    2       SORT (ORDER BY STOPKEY) (Cost=2364 Card=200000 Bytes=2400000)
   4    3         TABLE ACCESS (FULL) OF 'TABLENAME' (Cost=552 Card=200000 Bytes=2400000)
SQL> set autot off
SQL>
SQL> EXECUTE DBMS_STATS.GATHER_TABLE_STATS(user,'TABLENAME',METHOD_OPT => 'FOR COLUMNS SIZE 250 columna')
PL/SQL procedure successfully completed.
Elapsed: 00:00:09.08
SQL>
SQL> set autotrace on explain
SQL> SELECT * FROM
  2  (SELECT * FROM tablename WHERE columnA= 'ABC' ORDER BY TIME DESC)
  3  WHERE rownum <= 10
  4  /
TIME     COL
17/09/06 ABC
12/09/06 ABC
08/09/06 ABC
07/09/06 ABC
25/08/06 ABC
22/08/06 ABC
13/08/06 ABC
08/07/06 ABC
14/06/06 ABC
01/05/06 ABC
10 rows selected.
Elapsed: 00:00:01.03
Execution Plan
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=1434 Card=10 Bytes=120)
   1    0   COUNT (STOPKEY)
   2    1     VIEW (Cost=1434 Card=110806 Bytes=1329672)
   3    2       SORT (ORDER BY STOPKEY) (Cost=1434 Card=110806 Bytes=1329672)
   4    3         TABLE ACCESS (FULL) OF 'TABLENAME' (Cost=552 Card=110806 Bytes=1329672)
SQL>
SQL> SELECT * FROM
  2  (SELECT * FROM tablename WHERE columnA= 'MNO' ORDER BY TIME DESC)
  3  WHERE rownum <= 10
  4  /
TIME     COL
20/09/06 MNO
19/09/06 MNO
16/09/06 MNO
14/09/06 MNO
13/09/06 MNO
10/09/06 MNO
06/09/06 MNO
05/09/06 MNO
03/09/06 MNO
02/09/06 MNO
10 rows selected.
Elapsed: 00:00:02.05
Execution Plan
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=6219 Card=10 Bytes=120)
   1    0   COUNT (STOPKEY)
   2    1     VIEW (Cost=6219 Card=555198 Bytes=6662376)
   3    2       SORT (ORDER BY STOPKEY) (Cost=6219 Card=555198 Bytes=6662376)
   4    3         TABLE ACCESS (FULL) OF 'TABLENAME' (Cost=552 Card=555198 Bytes=6662376)
SQL>
SQL> SELECT * FROM
  2  (SELECT * FROM tablename WHERE columnA= 'STU' ORDER BY TIME DESC)
  3  WHERE rownum <= 10
  4  /
no rows selected
Elapsed: 00:00:00.00
Execution Plan
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=6 Card=1 Bytes=12)
   1    0   COUNT (STOPKEY)
   2    1     VIEW (Cost=6 Card=1 Bytes=12)
3 2 SORT (ORDER BY STOPKEY) (Cost=6 Card=1 Bytes=12)
4 3 TABLE ACCESS (BY INDEX ROWID) OF 'TABLENAME' (Cost=5 Card=1 Bytes=12)
5 4 INDEX (RANGE SCAN) OF 'I2' (NON-UNIQUE) (Cost=4 Card=1)
SQL> Nicolas.

Similar Messages

Maybe you are looking for

  • How do I get the latest drivers for windows 7 boot camp install?

    I have a 24" mac early 2009. I had windows xp installed on a partition using an early edition of boot camp. I had to reformat my mac and so I purchased windows 7 home premium oem edition.  When I try to install and copy boot camp drives to a 32 gb us

  • Captiure duties for import PO..?

    hi Pls guide me with more clear picture in excise duty capture and posting for import PO. whether i have to maintain any tax code with excise duties , or i have to maintain zero + nil excise duties in PO. and when i have capture and post excise dutie

  • Supplier Statement

    Hi, We are on R12.0.4. I want to know is there any report which gives me the Supplier Balance. Can we use Open Accounts Payables balance Listing report for the same. Regards/Prasanth

  • I have completed the upgrade to OS X Yosemite on my MacBook 5,4 only to find that iPhoto will not open. Can anyone help me please.l

    just completed the upgrade to os x Yosemite on my MacBook 5,4 only to find that iPhoto will not open. It came up with a message that I go to the app store and upgrade to the latest version of iPhoto , however the App Store also refuses to open. I wou

  • PSCC2014 dodge/burn weak?

    Installed on my WIN 7-64 system are PS CS6, PS CC and PS CC2014 (each used with a Wacom Intuos 4 tablet, with latest driver). In CC 2014, I notice that now the dodge / burn tool (s) seem to be significantly 'weakened': what used to take a few brush s