Oracle FAQ Your Portal to the Oracle Knowledge Grid
HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US
 

Home -> Community -> Usenet -> c.d.o.server -> Re: Tkprof result reading

Re: Tkprof result reading

From: Thomas Kyte <tkyte_at_us.oracle.com>
Date: 26 Jun 2001 10:14:08 -0700
Message-ID: <9haft0022l3@drn.newsguy.com>

In article <bd9a9a76.0106260807.1ab498ed_at_posting.google.com>, bchorng_at_yahoo.com says...
>
>Thomas Kyte <tkyte_at_us.oracle.com> wrote in message
>news:<9h8q7g02cr6_at_drn.newsguy.com>...
>>In article <bd9a9a76.0106251145.76ff5220_at_posting.google.com>, bchorng_at_yahoo.com
>:
>: < lines deleted>
>:
>>
>>so, in my case, it means I was doing a select for update on an unindexed table
>> -- the execute phase had to do it 100 times, the fetch phase once.
>>
>>
>> Are you doing something similar?
>>
>
>Thomas, this SQL is a pure select. I did not write it, it came from
>our
>application. Here is the complete information:
>
>********************************************************************************
>
>SELECT COUNT(*)
>FROM
> SPDUAL WHERE EXISTS (SELECT R.ID FROM ROLEPRIVILEGE
>RP,ROLEMEMBERSHIP RM,
> ROLE R WHERE RM.PERSON_ID = :b1 AND R.ENTITY_TYPE = 'G' AND R.ID
>=
> RM.ROLE_ID AND RP.RESTRICTION_ID = 1 AND RM.ROLE_ID = RP.ROLE_ID
>AND
> RP.PRIVILEGE_ID = :b2 )
>

This is much better - the query, the version, the OS..., ok, apparently, much of the work of the EXISTS is being counted in the EXECUTE phase of the query. Consider this small example:

ops$tkyte_at_ORA817.US.ORACLE.COM> create table spdual as select * from dual; Table created.

ops$tkyte_at_ORA817.US.ORACLE.COM> create table t1 as select rownum r, rpad('*',3000,'*') data from all_objects where rownum <= 20;

Table created.

On my system (8k blocks) that created a 10 block table. Now I run a block of code:

ops$tkyte_at_ORA817.US.ORACLE.COM> declare
  2 l_cnt number;
  3 begin

  4          for i in 1 .. 3003
  5          loop
  6                  select count(*) into l_cnt
  7                    from spdual Test_1
  8                   where exists ( select NULL from t1 where r = (i-2990) );
  9          end loop;

 10 end;
 11 /

PL/SQL procedure successfully completed.

The TKPROF for that query shows:

SELECT COUNT(*)
FROM
 SPDUAL TEST_1 WHERE EXISTS (SELECT NULL FROM T1 WHERE R = (:b1 - 2990   ) )

call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ----------

Parse        1      0.00       0.00          0          0          0           0
Execute   3003      1.09       1.00         10      41961      36036           0
Fetch     3003      0.05       0.03          1         65        156        3003
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total     6007      1.14       1.03         11      42026      36192        3003

Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 334 (OPS$TKYTE) (recursive depth: 1)

Rows Row Source Operation

-------  ---------------------------------------------------
   3003  SORT AGGREGATE
     13   FILTER
     13    TABLE ACCESS FULL SPDUAL

   3003 TABLE ACCESS FULL T1 Now, when I index the table:

ops$tkyte_at_ORA817.US.ORACLE.COM> create index t1_idx on t1(r); Index created.

ops$tkyte_at_ORA817.US.ORACLE.COM> declare
  2 l_cnt number;
  3 begin

  4          for i in 1 .. 3003
  5          loop
  6                  select count(*) into l_cnt
  7                    from spdual Test_2
  8                   where exists ( select NULL from t1 where r = (i-2990) );
  9          end loop;

 10 end;
 11 /

PL/SQL procedure successfully completed.

SELECT COUNT(*)
FROM
 SPDUAL TEST_2 WHERE EXISTS (SELECT NULL FROM T1 WHERE R = (:b1 - 2990   ) )

call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ----------

Parse        1      0.00       0.00          0          0          0           0
Execute   3003      0.35       0.41          0       3003          0           0
Fetch     3003      0.04       0.06          0         65        156        3003
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total     6007      0.39       0.47          0       3068        156        3003

Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 334 (OPS$TKYTE) (recursive depth: 1)

Rows Row Source Operation

-------  ---------------------------------------------------
   3003  SORT AGGREGATE
     13   FILTER
     13    TABLE ACCESS FULL SPDUAL

   3003 INDEX RANGE SCAN (object id 69831)

We can see the work during the execute when wwaaayyy down. the execute phase was counting the work done by the where exists.

Now, to analyze your results:

>
>call count cpu elapsed disk query current rows
>------- ------ ------ ------- ---------- ---------- ---------- ----------
>Parse 1 0.02 0.00 0 0 0 0
>Execute 3003 0.88 0.70 3 30030 0 0
>Fetch 3003 0.13 0.20 2 3003 12012 3003
>------- ------ ------ ------- ---------- ---------- ---------- ----------
>total 6007 1.03 0.90 5 33033 12012 3003

That says we process 30030 logical I/Os (average of 10 blocks per query) in the WHERE EXISTS you have.

The Fetch phase has 12012 current mode reads -- thats to perform the full scan of SPDUAL (looks like your where exists was satisified each and every time, 12012/3003 = 4 and in 817 i would expect 4 current mode reads).

The fetch phase has 3003 query mode gets, your spdual table must be 1 block big.

>
>Misses in library cache during parse: 1
>Optimizer goal: CHOOSE
>Parsing user id: 245 (TRAIN_ENCORE) (recursive depth: 1)
>
>Rows Execution Plan
>------- ---------------------------------------------------
> 0 SELECT STATEMENT GOAL: CHOOSE
> 0 SORT (AGGREGATE)
> 0 FILTER
> 0 TABLE ACCESS GOAL: ANALYZED (FULL) OF 'SPDUAL'
> 0 NESTED LOOPS
> 0 NESTED LOOPS
> 0 INDEX GOAL: ANALYZED (RANGE SCAN) OF
> 'PK_ROLEMEMBERSHIP' (UNIQUE)
> 0 TABLE ACCESS GOAL: ANALYZED (BY INDEX ROWID) OF
> 'ROLE'
> 0 INDEX GOAL: ANALYZED (UNIQUE SCAN) OF
> 'SYS_C00215078' (UNIQUE)
> 0 TABLE ACCESS GOAL: ANALYZED (BY INDEX ROWID) OF
> 'ROLEPRIVILEGE'
> 0 INDEX GOAL: ANALYZED (UNIQUE SCAN) OF
> 'PK_ROLEPRIVILEGE' (UNIQUE)
>
>********************************************************************************
>
>Another question I have is, why are the rows column all 0 in explain
>plan ? I exited out of the application before tkprofing.
>

that, i cannot answer -- as you can see with mine (also 817 on solaris) they were there. These numbers get recorded when the cursor itself is closed. I think that the process that ran this query did not exit "all of the way" - perhaps there is a middle tier involved?

>By the way, this is 8.1.7 on Solaris 2.7
>
>Thanks.
>
>-Bass Chorng

--
Thomas Kyte (tkyte@us.oracle.com)             http://asktom.oracle.com/ 
Expert one on one Oracle, programming techniques and solutions for Oracle.
http://www.amazon.com/exec/obidos/ASIN/1861004826/  
Opinions are mine and do not necessarily reflect those of Oracle Corp 
Received on Tue Jun 26 2001 - 12:14:08 CDT

Original text of this message

HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US