Note that there are some explanatory texts on larger screens.

plurals
  1. POAn oracle performance issue on COUNT()
    primarykey
    data
    text
    <p>I'm using Oracle 11g, the main table has about 10m records. Here is my query:</p> <pre><code>SELECT COUNT (*) FROM CONTACT c INNER JOIN STATUS S ON C.STATUS = S.STATUS WHERE C.USER = 1 AND S.REQUIRE = 1 AND ROWNUM = 1; </code></pre> <p>The Cost is 3736, but when I changed it to this form:</p> <pre><code>SELECT COUNT (*) FROM (SELECT 1 FROM CONTACT c INNER JOIN STATUS S ON C.STATUS = S.STATUS WHERE C.USER = 1 AND S.REQUIRE = 1 AND ROWNUM = 1); </code></pre> <p>The Cost became 5! What's the difference between these 2 queries?</p> <p>Here are the explain plan for both query:</p> <p>The first query:</p> <pre><code>---------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 10 | 3736 (1)| 00:00:45 | | 1 | SORT AGGREGATE | | 1 | 10 | | | |* 2 | COUNT STOPKEY | | | | | | | 3 | NESTED LOOPS | | 4627 | 46270 | 3736 (1)| 00:00:45 | | 4 | TABLE ACCESS BY INDEX ROWID| CONTACT | 6610 | 33050 | 3736 (1)| 00:00:45 | |* 5 | INDEX RANGE SCAN | IX_CONTACT_USR | 6610 | | 20 (0)| 00:00:01 | |* 6 | INDEX RANGE SCAN | IX_CONTACT_STATUS | 1 | 5 | 0 (0)| 00:00:01 | ---------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter(ROWNUM=1) 5 - access("C"."USER"=1) 6 - access("C"."STATUS"="S"."STATUS" AND "S"."REQUIRE"=1) </code></pre> <p>The second query:</p> <pre><code>----------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ----------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 5 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | | | | | 2 | VIEW | | 1 | | 5 (0)| 00:00:01 | |* 3 | COUNT STOPKEY | | | | | | | 4 | NESTED LOOPS | | 2 | 20 | 5 (0)| 00:00:01 | | 5 | TABLE ACCESS BY INDEX ROWID| CONTACT | 3 | 15 | 5 (0)| 00:00:01 | |* 6 | INDEX RANGE SCAN | IX_CONTACT_USR | 6610 | | 3 (0)| 00:00:01 | |* 7 | INDEX RANGE SCAN | IX_CONTACT_STATUS | 1 | 5 | 0 (0)| 00:00:01 | ----------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 3 - filter(ROWNUM=1) 6 - access("C"."USER"=1) 7 - access("C"."STATUS"="S"."STATUS" AND "S"."REQUIRE"=1) </code></pre> <p>I executed 2 queries, the first one sometimes cost 45s+ (e.g. first run or change the user id), otherwise it will cost &lt;1s. I totally don't know why it's such different, maybe db cache?</p> <p>When I executed the second query, I can always get result in 1s. So I think the second one is better, but I don't the reason why it improves a lot.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload