Query regarding Explain Plan
Hi,
I have a query regarding explain plan. While we gather the statistics then optimize choose the best possible plan out of the explain plans available. If we do not gather statistics on a table for a long time then which plan it choose:
If it will continue to use the same plan as it use in the starting when statistics were gathered or will change the plan as soon as dml activities performed and statistics getting old.
Thanks
GK
Hi,
Aman.... wrote:
Gulshan wrote:
Hi,
I have a query regarding explain plan. While we gather the statistics then optimize choose the best possible plan out of the explain plans available. If we do not gather statistics on a table for a long time then which plan it choose:The same plan which it has chosen in the starting with the previous statistics. The plan won't change automatically as long as you won't refresh the statistics. This is wrong even for Oracle 9i. Here are couple of examples when a plan might change with the same optimizer statistics:
* when you have a histogram on a column and are not a bright person to use bind variables, you might get a completely different execution plan because of a different incoming value. All that is needed to fall into this habit - a soft parse, which might be due to different reasons, for instance, due to session parameter modification (which also might change a plan even without a histogram)
* Starting with 10g, CBO makes adjustments to cardinality estimates for out of range values appeared in predicates
Similar Messages
-
Query Regarding Explain Plan on Query
Hello,
I have one big query which shows report of 50000 daily records from @ 20,00,000 records.
I have two databases UAT and PROD.when i do Explain Plan on the query is these different database i get the different plan where everything is same in both database.
In UAT it is doing Index scan where as in PROD it is doing Full TableScan. Below are the results.
In production it is not using any of the indexes present but in UAT it is.What could be the reasong behind this?Sure.
UAT Explain Plan (Please copy in Textpad for better View)
SELECT STATEMENT, GOAL = HINT: ALL_ROWS Cost=371 Cardinality=238 Optimizer=HINT: ALL_ROWS Bytes=134470
VIEW Object owner=SWNET1 Cost=371 Cardinality=238 Bytes=134470
COUNT STOPKEY
VIEW Object owner=SWNET1 Cost=371 Cardinality=238 Bytes=131376
SORT ORDER BY STOPKEY Cost=371 Cardinality=238 Bytes=54026
FILTER
HASH JOIN RIGHT ANTI Cost=370 Cardinality=238 Bytes=54026
INLIST ITERATOR
TABLE ACCESS BY INDEX ROWID Object owner=SWNET1 Object name=IS_TB_END_POINT Cost=1 Cardinality=1 Optimizer=ANALYZED Bytes=31
INDEX RANGE SCAN Object owner=SWNET1 Object name=IS_UK_EP_NAME Cost=1 Cardinality=1 Optimizer=ANALYZED
TABLE ACCESS BY INDEX ROWID Object owner=SWNET1 Object name=IS_TB_TRANSACTION Cost=368 Cardinality=253 Optimizer=ANALYZED Bytes=49588
INDEX FULL SCAN Object owner=SWNET1 Object name=IS_IX_T_DESTINATION_EP Cost=18 Cardinality=13909 Optimizer=ANALYZED
PRODUCTION Explain Plan
SELECT STATEMENT, GOAL = HINT: ALL_ROWS Cost=65702 Cardinality=1000 Optimizer=HINT: ALL_ROWS Bytes=565000
VIEW Object owner=SWNET1 Cost=65702 Cardinality=1000 Bytes=565000
COUNT STOPKEY
VIEW Object owner=SWNET1 Cost=65702 Cardinality=38739 Bytes=21383928
SORT ORDER BY STOPKEY Cost=65702 Cardinality=38739 Bytes=9646011
FILTER
HASH JOIN RIGHT ANTI Cost=63616 Cardinality=38739 Bytes=9646011
INLIST ITERATOR
TABLE ACCESS BY INDEX ROWID Object owner=SWNET1 Object name=IS_TB_END_POINT Cost=1 Cardinality=2 Optimizer=ANALYZED Bytes=64
INDEX UNIQUE SCAN Object owner=SWNET1 Object name=IS_UK_EP_NAME Cost=1 Cardinality=2 Optimizer=ANALYZED
TABLE ACCESS FULL Object owner=SWNET1 Object name=IS_TB_TRANSACTION Cost=63614 Cardinality=44697 Optimizer=ANALYZED Bytes=9699249
Index Query (Same on both places)
create index IS_IX_T_DESTINATION_EP on IS_TB_TRANSACTION (T_DESTINATION_EP)
tablespace IS_XML_IND
pctfree 10
initrans 2
maxtrans 255
storage
initial 128M
next 128K
minextents 1
maxextents unlimited
pctincrease 0
); -
1)explain plan
set statement_id='anu_a_1'
for select i.name from a i,b j
where i.id=j.id1
order by i.id
when i am trying to select rows from plan table
what is the purpose of id,parent_id column
what is the meaning of these output which is associated with 1st query.
OPERATION OPTIONS
SORT ORDER BY
when i am trying to run 2nd query
2)explain plan
set statement_id='anu_a_1'
for select * from a
where id=10
order by id
OPERATION OPTIONS
SORT ORDER BY
these are not come
why i am using here same order by clause.Study the documentation.
http://download-uk.oracle.com/docs/cd/B10501_01/server.920/a96533/opt_ops.htm#1005137
SORT ORDER BY
SORT ORDER BY is required when the statement specifies an ORDER BY that cannot be satisfied by one of the indexes
Rgds. -
General queries regarding explain plan and query
Hello Oracle buddies,
I have few badly formed queries with plenty of nested loops, merge join cartesian , plenty of sorting and in the query so many sub queries and all.. The cost of the queries are high like anything.
some even has 130Crore of cost .
When I got the chance to look into those quries I test them in Non Prod systems and which almost have 90-95% similar data as it was refresh by PROD few weeks back.
I found few queries are having the same explain plan but cost is less like anything. for example 5000 or 6000.
When I check for the possibilities of wrong statistics I found they just collect with default setting...
In Non prod I saw only the auto stat job is ran and most of the tables are having the stats which are of last analyzed on the day of refresh.
Now what could be so differentiating factor that drives a queries' cost lesser than Prod systems, when the data is almost same. Also if prod ssystem is gather by only gather_schema_stat('SCHEMA_NAME') then it should carry the same stat in non prod while refreshing. I know ppl do not gather stat on test only auto job is running ...
I need to have clear prove before I can have a clear understanding..
Please help me to know what factors could be differentiating?
-Regards,
J_DBA_Souravj_DBA_sourav wrote:
Hello Jonathan,
Thanks for the reply. The team refreshed it, by expdp/impdp method where by default statistics are included. In that case?
Is this problem probable to happen due to statistics only or anything else is also responsible. Even the explain plan is same.
Please through some light on it.
Auto job is on as I stated earlier but in test systems most of the tables are showing refreshed date as last_analyzed
-Regards
JDS
Anything that puts the stats out of sync with each other may be sufficient to cause problems. Any queries that depend on sysdate may cause a problem.
As a simple check: select table_name, last_analyzed from user_tables on the two systems, with some order by clause (e.g. table_name), and see how many tables were analysed at different times - anything on either system after the exp/imp could be part of your problem.
Regards
Jonathan Lewis
http://jonathanlewis.wordpress.com
Now on Twitter: @jloracle -
Any room for improvement for this query? Explain Plan attached.
Is there any room for improvement for this query? Table stats are up-to-date. Any suggestions Query rewrite, addition of indexes,...etc ??
select sum(CONF
when (cd.actl_qty - cd.total_alloc_qty - lsd.Q < 0) then
0
else
cd.actl_qty - cd.total_alloc_qty - lsd.Q
end)
from (select sum(reqd_qty) as Q, ITEM_ID as ITEM
from SHIP_DTL SD
where exists (select 1
from CONF_dtl
where CONF_nbr = '1'
and ITEM_id = SD.ITEM_id)
group by ITEM_id) lsd,
CONF_dtl cd
where lsd.ITEM = cd.ITEM_id
and cd.CONF_nbr = '1'Total number of rows in the tables involved
select count(*) from CONF_DTL;
COUNT(*)
1785889
select count(*) from shp_dtl;
COUNT(*)
286675
Explain Plan
PLAN_TABLE_OUTPUT
Plan hash value: 2325658044
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 39 | 4 (25)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 39 | | |
| 2 | VIEW | | 1 | 39 | 4 (25)| 00:00:01 |
| 3 | HASH GROUP BY | | 1 | 117 | 4 (25)| 00:00:01 |
| 4 | TABLE ACCESS BY INDEX ROWID | SHIP_DTL | 1 | 15 | 1 (0)| 00:00:01
| 5 | NESTED LOOPS | | 1 | 117 | 3 (0)| 00:00:01 |
| 6 | MERGE JOIN CARTESIAN | | 1 | 102 | 2 (0)| 00:00:01 |
| 7 | TABLE ACCESS BY INDEX ROWID | CONF_DTL | 1 | 70 | 1 (0)| 00:00:01 |
|* 8 | INDEX RANGE SCAN | PK_CONF_DTL | 1 | | 1 (0)| 00:00:01 |
| 9 | BUFFER SORT | | 1 | 32 | 1 (0)| 00:00:01 |
| 10 | SORT UNIQUE | | 1 | 32 | 1 (0)| 00:00:01 |
| 11 | TABLE ACCESS BY INDEX ROWID| CONF_DTL | 1 | 32 | 1 (0)| 00:00:01 |
|* 12 | INDEX RANGE SCAN | PK_CONF_DTL | 1 | | 1 (0)| 00:00:01 |
|* 13 | INDEX RANGE SCAN | SHIP_DTL_IND_6 | 1 | | 1 (0)| 00:00:01 |
Predicate Information (identified by operation id):
8 - access("CD"."CONF_NBR"='1')
12 - access("CONF_NBR"='1')
13 - access("ITEM_ID"="SD"."ITEM_ID")
filter("ITEM_ID"="CD"."ITEM_ID")Citizen_2 wrote:
Is there any room for improvement for this query? Table stats are up-to-date. Any suggestions Query rewrite, addition of indexes,...etc ??You say that the table stats are up-to-date, but is the following assumption of the optimizer correct:
select count(*)
from CONF_dtl
where CONF_nbr = '1';Does this query return a count of 1? I doubt that, but that's what Oracle estimates in the EXPLAIN PLAN output. Based on that assumption you get a cartesian join between the two CONF_DTL table instances, and the result - which is still expected to be one row at most - is then joined to the SHIP_DTL table using a NESTED LOOP.
If above assumption is incorrect, the number of rows generated by the cartesian join can be tremendous rendering the NESTED LOOP operation quite inefficient.
You can verify this by using the DBMS_XPLAN.DISPLAY_CURSOR function together with the GATHER_PLAN_STATISTICS hint, if you're already on 10g or later.
For more information regarding the DISPLAY_CURSOR function, see e.g. here: http://jonathanlewis.wordpress.com/2006/11/09/dbms_xplan-in-10g/
It will show you the actual cardinalities compared to the estimated cardinalities.
If the estimate of the optimizer is incorrect, you should find out why. There still might be some issues with the statistics, since this is most obvious reason for incorrect estimates.
Are your index statistics up-to-date?
Regards,
Randolf
Oracle related stuff blog:
http://oracle-randolf.blogspot.com/
SQLTools++ for Oracle (Open source Oracle GUI for Windows):
http://www.sqltools-plusplus.org:7676/
http://sourceforge.net/projects/sqlt-pp/ -
Suppose, i am using two queries [ which are almost equal] but using separate table name aliases. Will this result is separate Explain Plans?
i.e.
Explain Plan for : Select * from emp a;
and Explain for : Select * from emp b;
Will remain same always, or it will differ?
Also, i was looking for low level conversion of Parsed SQL statements to Machine Level Language. I mean how this step is performed. Where does the compiler/interpreter resides and how it works.
Thanks in Advance.
Regards,
Sudipta.user13513014 wrote:
Suppose, i am using two queries [ which are almost equal] but using separate table name aliases. Will this result is separate Explain Plans?
i.e.
Explain Plan for : Select * from emp a;
and Explain for : Select * from emp b;
Will remain same always, or it will differ? By simply switching alias, the optimizer is unlikely to develop a new plan.
Also, i was looking for low level conversion of Parsed SQL statements to Machine Level Language. I mean how this step is performed. Where does the compiler/interpreter resides and how it works.
Thanks in Advance.
Regards,
Sudipta.There is no way you can actally see the parsing of SQL. It is done internally by oracle in a process caled Hard Parse or Soft Parse. A Hard Parse is where the optimizer must go through all the steps of parsing from the beggining, where as a soft parse, oracle uses the cached results from a hard parsed query that is in the shared pool.
How the optimizer works is a subject of ample documentation and several books. As a general over view, here are the general steps at parsing an SQL:
1. Optimizer evaluates your statement, checks it for grammar errors, grants to objects, etc.
2. Statement Transformation: Optimizer evaluates your statement for possible optimization regarding rewrite, in cases you have view or correlated subqueries.
3. Choice of optimizer goals.
4. Choice of acccess paths.
5. Choice of Join Orders.
Suggest you try a google search, it will give you a lot of material, or check the Oracle Database Performance Tuning Guide 11.2, which is free by oracle. -
How to improve the query performance or tune query from Explain Plan
Hi
The following is my explain plan for sql query. (The plan is generated by Toad v9.7). How to fix the query?
SELECT STATEMENT ALL_ROWSCost: 4,160 Bytes: 25,296 Cardinality: 204
8 NESTED LOOPS Cost: 3 Bytes: 54 Cardinality: 1
5 NESTED LOOPS Cost: 2 Bytes: 23 Cardinality: 1
2 TABLE ACCESS BY INDEX ROWID TABLE AR.RA_CUSTOMER_TRX_ALL Cost: 1 Bytes: 13 Cardinality: 1
1 INDEX UNIQUE SCAN INDEX (UNIQUE) AR.RA_CUSTOMER_TRX_U1 Cost: 1 Cardinality: 1
4 TABLE ACCESS BY INDEX ROWID TABLE AR.HZ_CUST_ACCOUNTS Cost: 1 Bytes: 10 Cardinality: 1
3 INDEX UNIQUE SCAN INDEX (UNIQUE) AR.HZ_CUST_ACCOUNTS_U1 Cost: 1 Cardinality: 1
7 TABLE ACCESS BY INDEX ROWID TABLE AR.HZ_PARTIES Cost: 1 Bytes: 31 Cardinality: 1
6 INDEX UNIQUE SCAN INDEX (UNIQUE) AR.HZ_PARTIES_U1 Cost: 1 Cardinality: 1
10 TABLE ACCESS BY INDEX ROWID TABLE AR.RA_CUSTOMER_TRX_ALL Cost: 1 Bytes: 12 Cardinality: 1
9 INDEX UNIQUE SCAN INDEX (UNIQUE) AR.RA_CUSTOMER_TRX_U1 Cost: 1 Cardinality: 1
15 NESTED LOOPS Cost: 2 Bytes: 29 Cardinality: 1
12 TABLE ACCESS BY INDEX ROWID TABLE AR.RA_CUSTOMER_TRX_ALL Cost: 1 Bytes: 12 Cardinality: 1
11 INDEX UNIQUE SCAN INDEX (UNIQUE) AR.RA_CUSTOMER_TRX_U1 Cost: 1 Cardinality: 1
14 TABLE ACCESS BY INDEX ROWID TABLE ONT.OE_ORDER_HEADERS_ALL Cost: 1 Bytes: 17 Cardinality: 1
13 INDEX RANGE SCAN INDEX (UNIQUE) ONT.OE_ORDER_HEADERS_U2 Cost: 1 Cardinality: 1
21 FILTER
16 TABLE ACCESS FULL TABLE ONT.OE_TRANSACTION_TYPES_TL Cost: 2 Bytes: 1,127 Cardinality: 49
20 NESTED LOOPS Cost: 2 Bytes: 21 Cardinality: 1
18 TABLE ACCESS BY INDEX ROWID TABLE AR.RA_CUSTOMER_TRX_ALL Cost: 1 Bytes: 12 Cardinality: 1
17 INDEX UNIQUE SCAN INDEX (UNIQUE) AR.RA_CUSTOMER_TRX_U1 Cost: 1 Cardinality: 1
19 INDEX RANGE SCAN INDEX (UNIQUE) ONT.OE_ORDER_HEADERS_U2 Cost: 1 Bytes: 9 Cardinality: 1
23 TABLE ACCESS BY INDEX ROWID TABLE AR.RA_CUSTOMER_TRX_ALL Cost: 1 Bytes: 12 Cardinality: 1
22 INDEX UNIQUE SCAN INDEX (UNIQUE) AR.RA_CUSTOMER_TRX_U1 Cost: 1 Cardinality: 1
45 NESTED LOOPS Cost: 4,160 Bytes: 25,296 Cardinality: 204
42 NESTED LOOPS Cost: 4,150 Bytes: 23,052 Cardinality: 204
38 NESTED LOOPS Cost: 4,140 Bytes: 19,992 Cardinality: 204
34 NESTED LOOPS Cost: 4,094 Bytes: 75,850 Cardinality: 925
30 NESTED LOOPS Cost: 3,909 Bytes: 210,843 Cardinality: 3,699
26 PARTITION LIST ALL Cost: 2,436 Bytes: 338,491 Cardinality: 14,717 Partition #: 29 Partitions accessed #1 - #18
25 TABLE ACCESS BY LOCAL INDEX ROWID TABLE XLA.XLA_AE_HEADERS Cost: 2,436 Bytes: 338,491 Cardinality: 14,717 Partition #: 29 Partitions accessed #1 - #18
24 INDEX SKIP SCAN INDEX XLA.XLA_AE_HEADERS_N1 Cost: 264 Cardinality: 1,398,115 Partition #: 29 Partitions accessed #1 - #18
29 PARTITION LIST ITERATOR Cost: 1 Bytes: 34 Cardinality: 1 Partition #: 32
28 TABLE ACCESS BY LOCAL INDEX ROWID TABLE XLA.XLA_AE_LINES Cost: 1 Bytes: 34 Cardinality: 1 Partition #: 32
27 INDEX RANGE SCAN INDEX (UNIQUE) XLA.XLA_AE_LINES_U1 Cost: 1 Cardinality: 1 Partition #: 32
33 PARTITION LIST ITERATOR Cost: 1 Bytes: 25 Cardinality: 1 Partition #: 35
32 TABLE ACCESS BY LOCAL INDEX ROWID TABLE XLA.XLA_DISTRIBUTION_LINKS Cost: 1 Bytes: 25 Cardinality: 1 Partition #: 35
31 INDEX RANGE SCAN INDEX XLA.XLA_DISTRIBUTION_LINKS_N3 Cost: 1 Cardinality: 1 Partition #: 35
37 PARTITION LIST SINGLE Cost: 1 Bytes: 16 Cardinality: 1 Partition #: 38
36 TABLE ACCESS BY LOCAL INDEX ROWID TABLE XLA.XLA_EVENTS Cost: 1 Bytes: 16 Cardinality: 1 Partition #: 39 Partitions accessed #2
35 INDEX UNIQUE SCAN INDEX (UNIQUE) XLA.XLA_EVENTS_U1 Cost: 1 Cardinality: 1 Partition #: 40 Partitions accessed #2
41 PARTITION LIST SINGLE Cost: 1 Bytes: 15 Cardinality: 1 Partition #: 41
40 TABLE ACCESS BY LOCAL INDEX ROWID TABLE XLA.XLA_TRANSACTION_ENTITIES Cost: 1 Bytes: 15 Cardinality: 1 Partition #: 42 Partitions accessed #2
39 INDEX UNIQUE SCAN INDEX (UNIQUE) XLA.XLA_TRANSACTION_ENTITIES_U1 Cost: 1 Cardinality: 1 Partition #: 43 Partitions accessed #2
44 TABLE ACCESS BY INDEX ROWID TABLE GL.GL_CODE_COMBINATIONS Cost: 1 Bytes: 11 Cardinality: 1
43 INDEX UNIQUE SCAN INDEX (UNIQUE) GL.GL_CODE_COMBINATIONS_U1 Cost: 1 Cardinality: 1damorgan wrote:
Tuning is NOT about reducing the cost of i/o.
i/o is only one of many contributors to cost and only one of many contributors to waits.
Any time you would like to explore this further run this code:
SELECT 1 FROM dual
WHERE regexp_like(' ','^*[ ]*a');but not on a production box because you are going to experience an extreme tuning event with zero i/o.
And when I say "extreme" I mean "EXTREME!"
You've been warned.I think you just need a faster server.
SQL> set autotrace traceonly statistics
SQL> set timing on
SQL> select 1 from dual
2 where
3 regexp_like (' ','^*[ ]*a');
no rows selected
Elapsed: 00:00:00.00
Statistics
1 recursive calls
0 db block gets
0 consistent gets
0 physical reads
0 redo size
243 bytes sent via SQL*Net to client
349 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
0 rows processedRepeated from an Oracle 10.2.0.x instance:
SQL> SELECT DISTINCT SID FROM V$MYSTAT;
SID
310
SQL> ALTER SESSION SET EVENTS '10053 TRACE NAME CONTEXT FOREVER, LEVEL 1';
Session altered.
SQL> select 1 from dual
2 where
3 regexp_like (' ','^*[ ]*a');The session is hung. Wait a little while and connect to the database using a different session:
COLUMN STAT_NAME FORMAT A35 TRU
SET PAGESIZE 200
SELECT
STAT_NAME,
VALUE
FROM
V$SESS_TIME_MODEL
WHERE
SID=310;
STAT_NAME VALUE
DB time 9247
DB CPU 9247
background elapsed time 0
background cpu time 0
sequence load elapsed time 0
parse time elapsed 6374
hard parse elapsed time 5997
sql execute elapsed time 2939
connection management call elapsed 1660
failed parse elapsed time 0
failed parse (out of shared memory) 0
hard parse (sharing criteria) elaps 0
hard parse (bind mismatch) elapsed 0
PL/SQL execution elapsed time 95
inbound PL/SQL rpc elapsed time 0
PL/SQL compilation elapsed time 0
Java execution elapsed time 0
repeated bind elapsed time 48
RMAN cpu time (backup/restore) 0Seems to be using a bit of time for the hard parse (hard parse elapsed time). Wait a little while, then re-execute the query:
STAT_NAME VALUE
DB time 9247
DB CPU 9247
background elapsed time 0
background cpu time 0
sequence load elapsed time 0
parse time elapsed 6374
hard parse elapsed time 5997
sql execute elapsed time 2939
connection management call elapsed 1660
failed parse elapsed time 0
failed parse (out of shared memory) 0
hard parse (sharing criteria) elaps 0
hard parse (bind mismatch) elapsed 0
PL/SQL execution elapsed time 95
inbound PL/SQL rpc elapsed time 0
PL/SQL compilation elapsed time 0
Java execution elapsed time 0
repeated bind elapsed time 48
RMAN cpu time (backup/restore) 0The session is not reporting additional CPU usage or parse time.
Let's check one of the session's statistics:
SELECT
SS.VALUE
FROM
V$SESSTAT SS,
V$STATNAME SN
WHERE
SN.NAME='consistent gets'
AND SN.STATISTIC#=SS.STATISTIC#
AND SS.SID=310;
VALUE
163Not many consistent gets after 20+ minutes.
Let's take a look at the plan:
SQL> SELECT SQL_ID,CHILD_NUMBER FROM V$SQL WHERE SQL_TEXT LIKE 'select 1 from du
al%';
SQL_ID CHILD_NUMBER
04mpgrzhsv72w 0
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('04mpgrzhsv72w',0,'TYPICAL'))
select 1 from dual where regexp_like (' ','^*[ ]*a')
NOTE: cannot fetch plan for SQL_ID: 04mpgrzhsv72w, CHILD_NUMBER: 0
Please verify value of SQL_ID and CHILD_NUMBER;
It could also be that the plan is no longer in cursor cache (check v$sql_p
lan)No plan...
Let's take a look at the 10053 trace file:
Registered qb: SEL$1 0x19157f38 (PARSER)
signature (): qb_name=SEL$1 nbfros=1 flg=0
fro(0): flg=4 objn=258 hint_alias="DUAL"@"SEL$1"
Predicate Move-Around (PM)
PM: Considering predicate move-around in SEL$1 (#0).
PM: Checking validity of predicate move-around in SEL$1 (#0).
CBQT: Validity checks failed for 7uqx4guu04x3g.
CVM: Considering view merge in query block SEL$1 (#0)
CBQT: Validity checks failed for 7uqx4guu04x3g.
Subquery Unnest
SU: Considering subquery unnesting in query block SEL$1 (#0)
Set-Join Conversion (SJC)
SJC: Considering set-join conversion in SEL$1 (#0).
Predicate Move-Around (PM)
PM: Considering predicate move-around in SEL$1 (#0).
PM: Checking validity of predicate move-around in SEL$1 (#0).
PM: PM bypassed: Outer query contains no views.
FPD: Considering simple filter push in SEL$1 (#0)
FPD: Current where clause predicates in SEL$1 (#0) :
REGEXP_LIKE (' ','^*[ ]*a')
kkogcp: try to generate transitive predicate from check constraints for SEL$1 (#0)
predicates with check contraints: REGEXP_LIKE (' ','^*[ ]*a')
after transitive predicate generation: REGEXP_LIKE (' ','^*[ ]*a')
finally: REGEXP_LIKE (' ','^*[ ]*a')
apadrv-start: call(in-use=592, alloc=16344), compile(in-use=37448, alloc=42256)
kkoqbc-start
: call(in-use=592, alloc=16344), compile(in-use=38336, alloc=42256)
kkoqbc-subheap (create addr=000000001915C238)Looks like the query never had a chance to start executing - it is still parsing after 20 minutes.
I am not sure that this is a good example - the query either executes very fast, or never has a chance to start executing. But, it might still make your point physical I/O is not always the problem when performance problems are experienced.
Charles Hooper
IT Manager/Oracle DBA
K&M Machine-Fabricating, Inc. -
Understanding meaning of a query's explain plan
Hi,
I have a simple query but its query plan is looking difficult for me to understand. Can someone help me explain step by step what happens inthe query. I mean "first step table emp is full scan , than next step is another table's scan..." etc - in that way. I can't make out and need help to understand.
SQL> explain plan for
2 SELECT ename,dname ,grade
3 from n1.salgrade salgrade ,n1.emp emp,n1.dept dept
4 where emp.deptno=dept.deptno and
5 emp.sal between salgrade.losal and salgrade.hisal;
SQL> select plan_table_output from table(dbms_xplan.display());
Plan hash value: 4131418678
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 36 | 12 (25)| 00:00:01 |
|* 1 | HASH JOIN | | 1 | 36 | 12 (25)| 00:00:01 |
| 2 | MERGE JOIN | | 1 | 23 | 8 (25)| 00:00:01 |
| 3 | SORT JOIN | | 5 | 50 | 4 (25)| 00:00:01 |
| 4 | TABLE ACCESS FULL | SALGRADE | 5 | 50 | 3 (0)| 00:00:01 |
|* 5 | FILTER | | | | | |
|* 6 | SORT JOIN | | 14 | 182 | 4 (25)| 00:00:01 |
| 7 | TABLE ACCESS FULL| EMP | 14 | 182 | 3 (0)| 00:00:01 |
| 8 | TABLE ACCESS FULL | DEPT | 4 | 52 | 3 (0)| 00:00:01 |
Predicate Information (identified by operation id):
1 - access("EMP"."DEPTNO"="DEPT"."DEPTNO")
5 - filter("EMP"."SAL"<="SALGRADE"."HISAL")
6 - access("EMP"."SAL">="SALGRADE"."LOSAL")
filter("EMP"."SAL">="SALGRADE"."LOSAL")for example my question is why there is SORT JOIN on step no 6? does it mean that rows obtained from step 7 are sorted? than what is done during the step of FILTER?why there are so many joins. Basically I am not good in this area so need help.
Thanks
Edited by: orausern on Sep 23, 2010 11:58 AMThe operations are performed in the following order: 4, 3, 7, 6, 5, 2, 8, 1, 0. The Merge Join operation in Node 2 consumes the SALGRADE and EMP records produced by Node 3 and Node 5 respectively. Node 3 and Node 5 are therefore visited repeatedly during the Merge Join operation. Whenever Node 3 produces a SALGRADE record, Node 5 tries to produce matching EMP records. Node 6 produces EMP records that satisfy the condition EMP.SAL >= SALGRADE.LOSAL. Node 5 then checks if the EMP records produced by Node 6 satisfy the additional condition EMP.SAL <= SALGRADE.HISAL before releasing them. All the results of the Merge Join operation are stored in a hash table in memory. Once the construction of the hash table is fully complete, the DEPT table is scanned and each DEPT record is checked using the hash table.
Iggy -
hi all,
i am using database 10g.
i have explain as below
SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
PLAN_TABLE_OUTPUT
Plan hash value: 2715695103
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
|
| 0 | SELECT STATEMENT | | 8 | 568 | 6 (17)| 00:00:
01 |
| 1 | HASH UNIQUE | | 8 | 568 | 6 (17)| 00:00:
01 |
| 2 | NESTED LOOPS | | 8 | 568 | 5 (0)| 00:00:
01 |
|* 3 | TABLE ACCESS FULL | COMMON_PURCHASE_HEADER | 8 | 232 | 3 (0)| 00:00:
PLAN_TABLE_OUTPUT
01 |
| 4 | TABLE ACCESS BY INDEX ROWID| CUSTOMER_MASTER | 1 | 42 | 1 (0)| 00:00:
01 |
|* 5 | INDEX UNIQUE SCAN | CUM_PK | 1 | | 0 (0)| 00:00:
01 |
----how we can analyse the query based on this plan.
Thanks..What do you think an execution plan is? I think you think that this tells you all by itself how "good" the query is. No that's wrong. You can compare it with the advise a GPS system gives you to go from A to B. Some GPS system give better advices than others, some even know the current traffic situation. But, without any knowledge about the location you are in, you have to trust that plan.
But, if you live in that area, you might know that another path might me faster than the suggested one,etc.
All ORACLE tells you with this execution plan, is that it will read table COMMON_PURCHASE_HEADER completely and will join CUSTOMER_MASTER in a nested loop over the PK index.
WE do now know a lot about your DB, if there are other indexes (e.g. on C_STATUS) and what the cardinality on it is. If there would be an index, and the value A would just occur once, an INDEX lookup might be faster if you would have MUCH moire data!
On 8 rows....as the optimizer believes all data is on the same block and is read by 1 IO and that's the fastest access.
So, basically you need to learn what ORACLE tries to do.
Then you ask yourself, as you know the DB, if that's a clever idea.
If it's not, ask yourself why ORACLE does not agree with you. It might still be right. So test your access methods with hints, and you will see and learn.
As I said it's like the advice a GPS system gives you. Only a local can really tell you how clever that suggestion is. (And the local can be wrong) ;-) -
Is there any way to tune this query? EXPLAIN PLAN included
DB version:10gR2
The below query was taking more than 3 seconds. The statistics are up to date for these tables. Is there any other way i could tune this query?
SELECT COUNT(1)
FROM
INVN_SCOPE_DTL, ship_dtl WHERE ship_dtl.WHSE = INVN_SCOPE_DTL.WHSE (+)
AND 'QC' = INVN_SCOPE_DTL.FROM_WORK_GRP (+)
AND 'MQN' = INVN_SCOPE_DTL.FROM_WORK_AREA (+)
AND ship_dtl.START_CURR_WORK_GRP = INVN_SCOPE_DTL.TO_WORK_GRP (+)
AND ship_dtl.START_CURR_WORK_AREA = INVN_SCOPE_DTL.TO_WORK_AREA (+)
AND ship_dtl.WHSE = '930' AND ship_dtl.OWNER_USER_ID = 'CTZDM'
OR ship_dtl.OWNER_USER_ID = '*'
AND ship_dtl.STAT_CODE >= '10'
AND ship_dtl.STAT_CODE <= '20'
ORDER BY ship_dtl.OWNER_USER_ID DESC,
ship_dtl.CURR_TASK_PRTY ASC, INVN_SCOPE_DTL.DISTANCE ASC, ship_dtl.RLS_DATE_TIME ASC, ship_dtl.TASK_ID ASC;
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
| 0 | SELECT STATEMENT | | 1 | 86 | 86 (2)|
| 1 | SORT AGGREGATE | | 1 | 86 | |
| 2 | NESTED LOOPS OUTER | | 898 | 77228 | 86 (2)|
| 3 | INLIST ITERATOR | | | | |
|* 4 | TABLE ACCESS BY INDEX ROWID| ship_dtl | 898 | 31430 | 85 (2)|
|* 5 | INDEX RANGE SCAN | ship_dtl_IND_4 | 2876 | | 1 (0)|
| 6 | TABLE ACCESS BY INDEX ROWID | INVN_SCOPE_DTL | 1 | 51 | 2 (50)|
PLAN_TABLE_OUTPUT
|* 7 | INDEX UNIQUE SCAN | PK_INVN_SCOPE_DTL | 1 | | |
Predicate Information (identified by operation id):
4 - filter("ship_dtl"."WHSE"='930' AND "ship_dtl"."STAT_CODE">=10 AND
"ship_dtl"."STAT_CODE"<=20)
5 - access("ship_dtl"."OWNER_USER_ID"='*' OR "ship_dtl"."OWNER_USER_ID"='CTZDM')
7 - access("INVN_SCOPE_DTL"."WHSE"(+)='930' AND
"INVN_SCOPE_DTL"."FROM_WORK_GRP"(+)='QC' AND "INVN_SCOPE_DTL"."FROM_WORK_AREA"(+)='MQN'
PLAN_TABLE_OUTPUT
AND "ship_dtl"."START_CURR_WORK_GRP"="INVN_SCOPE_DTL"."TO_WORK_GRP"(+) AND
"ship_dtl"."START_CURR_WORK_AREA"="INVN_SCOPE_DTL"."TO_WORK_AREA"(+))
filter("ship_dtl"."WHSE"="INVN_SCOPE_DTL"."WHSE"(+))
25 rows selected.William Robertson wrote:
I notice an OR predicate in the middle of some AND predicates without explicit bracketing. Are you sure it does what you think it does?I underline this point.
A conjuction (AND expression) has a higher priority and will be executed (logically) before the disjunction (OR expression)! So your select looks like this
SELECT COUNT(1)
FROM INVN_SCOPE_DTL, ship_dtl
WHERE
( ship_dtl.WHSE = INVN_SCOPE_DTL.WHSE (+)
AND 'QC' = INVN_SCOPE_DTL.FROM_WORK_GRP (+)
AND 'MQN' = INVN_SCOPE_DTL.FROM_WORK_AREA (+)
AND ship_dtl.START_CURR_WORK_GRP = INVN_SCOPE_DTL.TO_WORK_GRP (+)
AND ship_dtl.START_CURR_WORK_AREA = INVN_SCOPE_DTL.TO_WORK_AREA (+)
AND ship_dtl.WHSE = '930'
AND ship_dtl.OWNER_USER_ID = 'CTZDM'
OR ( ship_dtl.OWNER_USER_ID = '*'
AND ship_dtl.STAT_CODE >= '10'
AND ship_dtl.STAT_CODE <= '20'
;This might be want you want, but I doubt it very much. Please add parenthesis', to get it working the way it should be.
Edited by: Sven W. on Oct 16, 2008 3:25 PM -
How i can obtain explain plan without run the query
Hello,
i need to know the result of explain of a query without run the query, it's this possible?
Thanks and best regards.explain plan for <your query>;
select * from table(dbms_xplan.display);Regards,
Rob. -
I am running the following query against my database
SELECT p.ID
FROM rap_counterparties cou,
rap_presentation_cou_ratings pcr,
rap_presentation_states sta,
rap_app_user_profiles aup,
rap_presentations p
WHERE cou.unt_id = aup.unt_id
AND aup.aur_id = 7529
AND pcr.cou_id = cou.ID
AND sta.cur_present_state_instance_flg = 'Y'
AND sta.state_type_id = pcr.pst_state_type_id
AND sta.pre_id = pcr.pst_pre_id
AND sta.state_type_id IN (326, 322, 323, 324, 325)
AND cou.unt_id = p.unt_id
AND p.ID = sta.pre_id
AND ( p.private_flg != 'Y'
OR (p.private_flg = 'Y' AND p.created_by_user_id = 10000083)
Explain plan of the query is
PLAN_TABLE_OUTPUT
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
| 0 | SELECT STATEMENT | | 8 | 456 | 3936 (16)|
|* 1 | TABLE ACCESS BY INDEX ROWID | RAP_PRESENTATIONS | 1 | 15 | 2 (50)|
| 2 | NESTED LOOPS | | 8 | 456 | 3936 (16)|
|* 3 | HASH JOIN | | 1745 | 73290 | 2145 (27)|
|* 4 | HASH JOIN | | 14257 | 431K| 1299 (25)|
|* 5 | HASH JOIN | | 5173 | 87941 | 583 (16)|
| 6 | TABLE ACCESS BY INDEX ROWID| RAP_APP_USER_PROFILES | 18 | 144 | 3 (34)|
|* 7 | INDEX RANGE SCAN | RAP_AUP_IX_01 | 18 | | 2 (50)|
| 8 | TABLE ACCESS FULL | RAP_COUNTERPARTIES | 118K| 1042K| 560 (13)|
|* 9 | INDEX FAST FULL SCAN | RAP_PCR_PK | 326K| 4467K| 659 (25)|
|* 10 | INDEX FAST FULL SCAN | RAP_PST_IX_02 | 120K| 1291K| 821 (29)|
|* 11 | INDEX RANGE SCAN | RAP_PRE_PK | 1 | | |
Predicate Information (identified by operation id):
1 - filter(("P"."PRIVATE_FLG"<>'Y' OR "P"."CREATED_BY_USER_ID"=10000083 AND
"P"."PRIVATE_FLG"='Y') AND "COU"."UNT_ID"="P"."UNT_ID")
3 - access("STA"."STATE_TYPE_ID"="PCR"."PST_STATE_TYPE_ID" AND
"STA"."PRE_ID"="PCR"."PST_PRE_ID")
4 - access("PCR"."COU_ID"="COU"."ID")
5 - access("COU"."UNT_ID"="AUP"."UNT_ID")
7 - access("AUP"."AUR_ID"=7529)
9 - filter("PCR"."PST_STATE_TYPE_ID"=322 OR "PCR"."PST_STATE_TYPE_ID"=323 OR
"PCR"."PST_STATE_TYPE_ID"=324 OR "PCR"."PST_STATE_TYPE_ID"=325 OR "PCR"."PST_STATE_TYPE_ID"=326)
10 - filter("STA"."CUR_PRESENT_STATE_INSTANCE_FLG"='Y' AND ("STA"."STATE_TYPE_ID"=322 OR
"STA"."STATE_TYPE_ID"=323 OR "STA"."STATE_TYPE_ID"=324 OR "STA"."STATE_TYPE_ID"=325 OR
"STA"."STATE_TYPE_ID"=326))
11 - access("P"."ID"="STA"."PRE_ID")
Table Row count
rap_app_user_profiles : 30639
rap_counterparties : 118583
rap_presentation_cou_ratings -- 652781
rap_presentation_states -- 982413
rap_presentations -- 246145
Questions
1. Why is the index not being used on the table rap_counterparties. If I force a hint then the index is being used
2. Is there a way I can have an index range scan as opposed to the index fast full scan.
3. This query runs in 3s. Is there anything else I can do to tune this query?
4. In predicate 9 and 10 the two tables have fast full scan. If the filter of unit generates only a few records why can't those few records be joined with these tables. Why the whole tables are first being scanned and then joined
Appreciate your responseThanks for the suggestions.
So I tried using the FIRST_ROW HINT and i am getting the nested loops join and it runs fast in 250ms.
SELECT /*+FIRST_ROWS*/
p.ID ID
FROM rap_presentations p,
rap_counterparties cou,
rap_presentation_states sta,
rap_presentation_cou_ratings pcr
WHERE cou.unt_id IN (
SELECT prof.unt_id
FROM rap_application_users u, rap_app_user_profiles prof
WHERE u.ID = prof.aur_id AND u.ID = 7529
AND prof.aro_id NOT IN (8))
AND cou.unt_id = p.unt_id
AND p.ID = sta.pre_id
AND sta.cur_present_state_instance_flg = 'Y'
AND sta.state_type_id = pcr.pst_state_type_id
AND sta.pre_id = pcr.pst_pre_id
AND pcr.cou_id = cou.ID
AND ( p.private_flg != 'Y'
OR (p.private_flg = 'Y' AND p.created_by_user_id = 7529)
AND sta.state_type_id IN (326, 322, 323, 324, 325)
Explain plan:
PLAN_TABLE_OUTPUT
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
| 0 | SELECT STATEMENT | | 7 | 434 | 43334 (2)|
|* 1 | TABLE ACCESS BY INDEX ROWID | RAP_PRESENTATIONS | 1 | 15 | 2 (50)|
| 2 | NESTED LOOPS | | 7 | 434 | 43334 (2)|
| 3 | NESTED LOOPS | | 1593 | 74871 | 41699 (2)|
| 4 | NESTED LOOPS | | 13016 | 457K| 15196 (2)|
| 5 | NESTED LOOPS | | 4723 | 101K| 798 (2)|
| 6 | VIEW | VW_NSO_1 | 16 | 208 | |
| 7 | SORT UNIQUE | | 16 | 256 | |
| 8 | NESTED LOOPS | | 16 | 256 | 4 (25)|
|* 9 | INDEX UNIQUE SCAN | RAP_AUR_PK | 1 | 5 | 2 (50)|
|* 10 | TABLE ACCESS BY INDEX ROWID| RAP_APP_USER_PROFILES | 16 | 176 | 3 (34)|
|* 11 | INDEX RANGE SCAN | RAP_AUP_IX_01 | 18 | | 2 (50)|
| 12 | TABLE ACCESS BY INDEX ROWID | RAP_COUNTERPARTIES | 295 | 2655 | 50 (2)|
|* 13 | INDEX RANGE SCAN | RAP_COU_IX_02 | 95 | | 2 (50)|
|* 14 | TABLE ACCESS BY INDEX ROWID | RAP_PRESENTATION_COU_RATINGS | 3 | 42 | 4 (25)|
|* 15 | INDEX RANGE SCAN | RAP_PCR_IX_03 | 10 | | 3 (34)|
|* 16 | INDEX RANGE SCAN | RAP_PST_IX_02 | 1 | 11 | 3 (34)|
|* 17 | INDEX RANGE SCAN | RAP_PRE_PK | 1 | | |
Predicate Information (identified by operation id):
1 - filter(("P"."PRIVATE_FLG"<>'Y' OR "P"."PRIVATE_FLG"='Y' AND "P"."CREATED_BY_USER_ID"=7529) AND
"COU"."UNT_ID"="P"."UNT_ID")
9 - access("U"."ID"=7529)
10 - filter("PROF"."ARO_ID"<>8)
11 - access("PROF"."AUR_ID"=7529)
13 - access("COU"."UNT_ID"="VW_NSO_1"."$nso_col_1")
14 - filter("PCR"."PST_STATE_TYPE_ID"=322 OR "PCR"."PST_STATE_TYPE_ID"=323 OR
"PCR"."PST_STATE_TYPE_ID"=324 OR "PCR"."PST_STATE_TYPE_ID"=325 OR "PCR"."PST_STATE_TYPE_ID"=326)
15 - access("PCR"."COU_ID"="COU"."ID")
16 - access("STA"."PRE_ID"="PCR"."PST_PRE_ID" AND "STA"."STATE_TYPE_ID"="PCR"."PST_STATE_TYPE_ID" AND
"STA"."CUR_PRESENT_STATE_INSTANCE_FLG"='Y')
filter("STA"."STATE_TYPE_ID"=322 OR "STA"."STATE_TYPE_ID"=323 OR "STA"."STATE_TYPE_ID"=324 OR
"STA"."STATE_TYPE_ID"=325 OR "STA"."STATE_TYPE_ID"=326)
17 - access("P"."ID"="STA"."PRE_ID")
But my query that runs to get the data has a union with another query and with the change it looks like below
SELECT /*+FIRST_ROWS*/
p.ID ID
FROM rap_presentations p,
rap_counterparties cou,
rap_presentation_states sta,
rap_presentation_cou_ratings pcr
WHERE cou.unt_id IN (
SELECT prof.unt_id
FROM rap_application_users u, rap_app_user_profiles prof
WHERE u.ID = prof.aur_id AND u.ID = 7529
AND prof.aro_id NOT IN (8))
AND cou.unt_id = p.unt_id
AND p.ID = sta.pre_id
AND sta.cur_present_state_instance_flg = 'Y'
AND sta.state_type_id = pcr.pst_state_type_id
AND sta.pre_id = pcr.pst_pre_id
AND pcr.cou_id = cou.ID
AND ( p.private_flg != 'Y'
OR (p.private_flg = 'Y' AND p.created_by_user_id = 7529)
AND sta.state_type_id IN (326, 322, 323, 324, 325)
UNION
SELECT /*+index(pfs)*/
p.ID ID
FROM rap_presentations p,
rap_presentation_states sta,
rap_facilities f,
rap_presentation_fac_states pfs
WHERE f.unt_id IN (
SELECT prof.unt_id
FROM rap_application_users u, rap_app_user_profiles prof
WHERE u.ID = prof.aur_id AND u.ID = 7529
AND prof.aro_id NOT IN (8))
AND f.unt_id = p.unt_id
AND p.ID = sta.pre_id
AND sta.cur_present_state_instance_flg = 'Y'
AND sta.state_type_id = pfs.pst_state_type_id
AND sta.pre_id = pfs.pst_pre_id
AND pfs.fac_id = f.ID
AND pfs.fac_num = f.num
AND f.current_facility_instance_flg = 'Y'
AND ( p.private_flg != 'Y'
OR (p.private_flg = 'Y' AND p.created_by_user_id = 7529)
AND sta.state_type_id IN (326, 322, 323, 324, 325)
Explain plan :
PLAN_TABLE_OUTPUT
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
| 0 | SELECT STATEMENT | | 8 | 534 | 14931 (80)|
| 1 | SORT UNIQUE | | 8 | 534 | 14931 (80)|
| 2 | UNION-ALL | | | | |
|* 3 | TABLE ACCESS BY INDEX ROWID | RAP_PRESENTATIONS | 1 | 15 | 2 (50)|
| 4 | NESTED LOOPS | | 7 | 455 | 3728 (17)|
|* 5 | HASH JOIN | | 1542 | 77100 | 2145 (27)|
|* 6 | HASH JOIN | | 12598 | 479K| 1300 (24)|
|* 7 | HASH JOIN | | 4571 | 111K| 584 (16)|
|* 8 | TABLE ACCESS BY INDEX ROWID| RAP_APP_USER_PROFILES | 16 | 176 | 3 (34)|
|* 9 | INDEX RANGE SCAN | RAP_AUP_IX_01 | 18 | | 2 (50)|
| 10 | NESTED LOOPS | | 118K| 1621K| 561 (13)|
|* 11 | INDEX UNIQUE SCAN | RAP_AUR_PK | 1 | 5 | 2 (50)|
| 12 | TABLE ACCESS FULL | RAP_COUNTERPARTIES | 118K| 1042K| 560 (13)|
|* 13 | INDEX FAST FULL SCAN | RAP_PCR_PK | 326K| 4467K| 659 (25)|
|* 14 | INDEX FAST FULL SCAN | RAP_PST_IX_02 | 120K| 1291K| 821 (29)|
|* 15 | INDEX RANGE SCAN | RAP_PRE_PK | 1 | | |
| 16 | NESTED LOOPS | | 1 | 79 | 11201 (2)|
| 17 | NESTED LOOPS | | 75 | 4800 | 11124 (2)|
| 18 | NESTED LOOPS | | 617 | 32701 | 9867 (2)|
| 19 | NESTED LOOPS | | 2104 | 69432 | 5606 (2)|
| 20 | NESTED LOOPS | | 16 | 256 | 4 (25)|
|* 21 | INDEX UNIQUE SCAN | RAP_AUR_PK | 1 | 5 | 2 (50)|
|* 22 | TABLE ACCESS BY INDEX ROWID| RAP_APP_USER_PROFILES | 16 | 176 | 3 (34)|
|* 23 | INDEX RANGE SCAN | RAP_AUP_IX_01 | 18 | | 2 (50)|
|* 24 | TABLE ACCESS BY INDEX ROWID | RAP_FACILITIES | 135 | 2295 | 351 (2)|
|* 25 | INDEX RANGE SCAN | RAP_FAC_IX_02 | 1608 | | 5 (20)|
|* 26 | INDEX RANGE SCAN | RAP_PFR_PK | 1 | 20 | 3 (34)|
|* 27 | INDEX RANGE SCAN | RAP_PST_IX_02 | 1 | 11 | 3 (34)|
|* 28 | TABLE ACCESS BY INDEX ROWID | RAP_PRESENTATIONS | 1 | 15 | 2 (50)|
|* 29 | INDEX UNIQUE SCAN | RAP_PRE_PK | 1 | | |
Predicate Information (identified by operation id):
3 - filter(("P"."PRIVATE_FLG"<>'Y' OR "P"."PRIVATE_FLG"='Y' AND "P"."CREATED_BY_USER_ID"=7529)
AND "COU"."UNT_ID"="P"."UNT_ID")
5 - access("STA"."STATE_TYPE_ID"="PCR"."PST_STATE_TYPE_ID" AND
"STA"."PRE_ID"="PCR"."PST_PRE_ID")
6 - access("PCR"."COU_ID"="COU"."ID")
7 - access("COU"."UNT_ID"="PROF"."UNT_ID")
8 - filter("PROF"."ARO_ID"<>8)
9 - access("PROF"."AUR_ID"=7529)
11 - access("U"."ID"=7529)
13 - filter("PCR"."PST_STATE_TYPE_ID"=322 OR "PCR"."PST_STATE_TYPE_ID"=323 OR
"PCR"."PST_STATE_TYPE_ID"=324 OR "PCR"."PST_STATE_TYPE_ID"=325 OR "PCR"."PST_STATE_TYPE_ID"=326)
14 - filter("STA"."CUR_PRESENT_STATE_INSTANCE_FLG"='Y' AND ("STA"."STATE_TYPE_ID"=322 OR
"STA"."STATE_TYPE_ID"=323 OR "STA"."STATE_TYPE_ID"=324 OR "STA"."STATE_TYPE_ID"=325 OR
"STA"."STATE_TYPE_ID"=326))
15 - access("P"."ID"="STA"."PRE_ID")
21 - access("U"."ID"=7529)
22 - filter("PROF"."ARO_ID"<>8)
23 - access("PROF"."AUR_ID"=7529)
24 - filter("F"."CURRENT_FACILITY_INSTANCE_FLG"='Y')
25 - access("F"."UNT_ID"="PROF"."UNT_ID")
26 - access("PFS"."FAC_ID"="F"."ID" AND "PFS"."FAC_NUM"="F"."NUM")
filter("PFS"."PST_STATE_TYPE_ID"=322 OR "PFS"."PST_STATE_TYPE_ID"=323 OR
"PFS"."PST_STATE_TYPE_ID"=324 OR "PFS"."PST_STATE_TYPE_ID"=325 OR "PFS"."PST_STATE_TYPE_ID"=326)
27 - access("STA"."PRE_ID"="PFS"."PST_PRE_ID" AND
"STA"."STATE_TYPE_ID"="PFS"."PST_STATE_TYPE_ID" AND "STA"."CUR_PRESENT_STATE_INSTANCE_FLG"='Y')
filter("STA"."STATE_TYPE_ID"=322 OR "STA"."STATE_TYPE_ID"=323 OR "STA"."STATE_TYPE_ID"=324
OR "STA"."STATE_TYPE_ID"=325 OR "STA"."STATE_TYPE_ID"=326)
28 - filter(("P"."PRIVATE_FLG"<>'Y' OR "P"."PRIVATE_FLG"='Y' AND "P"."CREATED_BY_USER_ID"=7529)
AND "F"."UNT_ID"="P"."UNT_ID")
29 - access("P"."ID"="STA"."PRE_ID")
Question:
1. When I put the query with the FIRST_ROWS hint in a union with another query, the explain plan reverts back to the older explain plan. how can I avoid it when running by iteslf it runs really quick?
2. Why is the cost with nested loops more higher? Is it because of statistics?
2. Does the database parameter db_multiblock_read_count have any affect on the fast full scan?
3. I gather statistics using the followin method
begin
dbms_stats.gather_schema_stats(
ownname => 'RAP_OWNER',
estimate_percent => dbms_stats.auto_sample_size,
method_opt => 'for all columns size auto',
degree => 7
end;
Sometimes I also use the following method
BEGIN
dbms_stats.gather_schema_stats( ownname=>'RAP_OWNER',
METHOD_OPT=>'FOR ALL INDEXED COLUMNS SIZE SKEWONLY',
CASCADE=>TRUE, ESTIMATE_PERCENT=>100);
END;
Which one is good or should I use both?
Appreciate your input. -
Cpu time is not getting displayed in explain plan
Hi All,
I am trying to analyze one query using explain plan .like below
1) explain plan for
SELECT /*+ parallel(tsp,8) use_hash( tsp tp) */ count(1)
FROM router tp,
receiver tsp
WHERE tp.rs = tsp.rp
AND creater_date >=to_date('04032009000000','ddmmyyyyhh24miss')
and tsp.XVF is not null
and tp.XVF is not null
and tp.role_name='BR';
2)@$ORACLE_HOME/rdbms/admin/utlxpls.sql
But i am getting only following columns in result .
| Id | Operation | Name | Rows | Bytes | Cost |
No Cpu time preset .
How can i extimate CPU time ?
Pls help
Thanksam_73798 wrote:
I am trying to analyze one query using explain plan .like below
But i am getting only following columns in result .
| Id | Operation | Name | Rows | Bytes | Cost |
No Cpu time preset .
How can i extimate CPU time ?You need to mention your database version (4-digits, e.g. 9.2.0.8).
In Oracle 9i CPU costing is disabled by default, you need to gather WORKLOAD system statistics to enable the CPU costing.
In 10g CPU costing is enabled by default and uses default NOWORKLOAD system statistics if no WORKLOAD system statistics have been gathered. It can only be disabled by setting an undocumented parameter or by changing the OPTIMIZER_FEATURES_ENABLE parameter back to 9i compatibility.
You can check the status of your system statistics by running the following query in SQL*Plus:
column sname format a20
column pname format a20
column pval2 format a20
select
sname
, pname
, pval1
, pval2
from
sys.aux_stats$;Can you show us the actual (complete) output you get from "utlxpls.sql"? Use the \ tag to preserve formatting here:
\output
\will show asoutput
Regards,
Randolf
Oracle related stuff blog:
http://oracle-randolf.blogspot.com/
SQLTools++ for Oracle (Open source Oracle GUI for Windows):
http://www.sqltools-plusplus.org:7676/
http://sourceforge.net/projects/sqlt-pp/ -
Filter(NULL IS NOT NULL) in Explain Plan ??
Hi All,
Can someone please explain what this explain plan statement means? I see a filter(NULL IS NOT NULL) as the first statement - could not figure out why it came up so from googling.
My Query Used:
EXPLAIN PLAN FOR
MERGE INTO summary_bysrccd
USING
(SELECT LAST_DAY(TRUNC(to_timestamp(os.requestdatetime, 'yyyymmddhh24:mi:ss.ff4'))) AS SUMMARY_DATE,
os.acctnum,
ol.sourcecode AS sourcecode,
ol.sourcename AS sourcename,
count(1) cnt_articleview
FROM article_views os , master_sourcecode ol
where os.sourcecode = ol.sourcecode
AND os.acctnum IS NOT NULL
AND ol.sourcecode IS NOT NULL
AND os.requestdatetime IS NOT NULL
AND UPPER(os.success_ind) = 'S'
AND (
('INCR' = 'FULL'
AND (get_date_timestamp(os.requestdatetime) BETWEEN TO_DATE('23-AUG-2011 00:00:00','DD-MON-YYYY HH24:MI:SS') AND TO_DATE('27-AUG-2011 23:59:59','DD-MON-YYYY HH24:MI:SS')
AND os.entry_CreatedDate BETWEEN TO_DATE('22-AUG-2011 00:00:00','DD-MON-YYYY HH24:MI:SS') AND TO_DATE('28-AUG-2011 00:00:00','DD-MON-YYYY HH24:MI:SS')
OR ('INCR' = 'FULL'
AND os.entry_createddate BETWEEN TO_DATE('23-AUG-2011 00:00:00','DD-MON-YYYY HH24:MI:SS') AND TO_DATE('27-AUG-2011 23:59:59','DD-MON-YYYY HH24:MI:SS') )
group by LAST_DAY(TRUNC(to_timestamp(os.requestdatetime, 'yyyymmddhh24:mi:ss.ff4'))),
os.acctnum,ol.sourcecode,ol.sourcename) mrg_query
ON (ods_av_summary_bysrccd.acctnum = mrg_query.acctnum AND
ods_av_summary_bysrccd.summary_date=mrg_query.summary_date AND
ods_av_summary_bysrccd.sourcecode=mrg_query.sourcecode)
WHEN NOT MATCHED THEN
INSERT (SUMMARY_date,ACCTNUM,SOURCECODE,SOURCENAME,CNT_ARTICLEVIEW,ENTRY_LASTUPDATEDDATE)
VALUES(mrg_query.summary_date,mrg_query.acctnum,mrg_query.sourcecode,mrg_query.sourcename,
mrg_query.cnt_articleview,sysdate)
WHEN MATCHED THEN
UPDATE SET ods_av_summary_bysrccd.cnt_articleview=
CASE WHEN NVL('INCR','INCR') = 'FULL' THEN mrg_query.cnt_articleview
ELSE ods_av_summary_bysrccd.cnt_articleview+mrg_query.cnt_articleview
END,
ods_av_summary_bysrccd.entry_lastupdateddate=sysdate;My Explain Plan:
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
Plan hash value: 268591246
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | Pstart| Pstop |
| 0 | MERGE STATEMENT | | 1 | 456 | | 3 (0)| 00:00:01 | | |
| 1 | MERGE | ODS_AV_SUMMARY_BYSRCCD | | | | | | | |
| 2 | VIEW | | | | | | | | |
| 3 | NESTED LOOPS OUTER | | 1 | 417 | | 3 (0)| 00:00:01 | | |
| 4 | VIEW | | 1 | 360 | | 5 (100)| 00:00:01 | | |
| 5 | SORT GROUP BY | | 1 | 73 | 595M| | | | |
PLAN_TABLE_OUTPUT
|* 6 | FILTER | | | | | | | | |
|* 7 | HASH JOIN | | 6975K| 485M| 3944K| 17594 (1)| 00:03:32 | | |
| 8 | TABLE ACCESS FULL | ODS_MASTER_SOURCECODE | 84021 | 2953K| | 273 (1)| 00:00:04 | | |
|* 9 | TABLE ACCESS BY GLOBAL INDEX ROWID| ODS_ARTICLE_VIEWS | 7007K| 247M| | 826 (0)| 00:00:10 | 33 | 33 |
|* 10 | INDEX FULL SCAN | IDX_AV_ACCTNUM | 25M| | | 26 (0)| 00:00:01 | | |
| 11 | TABLE ACCESS BY GLOBAL INDEX ROWID | ODS_AV_SUMMARY_BYSRCCD | 1 | 57 | | 3 (0)| 00:00:01 | ROWID | ROWID |
|* 12 | INDEX UNIQUE SCAN | ODS_AV_SUMMARY_BYSRCCD_PK | 1 | | | 2 (0)| 00:00:01 | | |
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
6 - filter(NULL IS NOT NULL)
7 - access("OS"."SOURCECODE"="OL"."SOURCECODE")
9 - filter("OS"."REQUESTDATETIME" IS NOT NULL AND "OS"."ENTRY_CREATEDDATE">=TO_DATE(' 2011-08-23 00:00:00', 'syyyy-mm-dd
hh24:mi:ss') AND "OS"."ENTRY_CREATEDDATE"<=TO_DATE(' 2011-08-27 23:59:59', 'syyyy-mm-dd hh24:mi:ss') AND UPPER("OS"."SUCCESS_IND")='S')
10 - filter("OS"."ACCTNUM" IS NOT NULL)
12 - access("ODS_AV_SUMMARY_BYSRCCD"."SUMMARY_DATE"(+)=INTERNAL_FUNCTION("MRG_QUERY"."SUMMARY_DATE") AND
"ODS_AV_SUMMARY_BYSRCCD"."ACCTNUM"(+)="MRG_QUERY"."ACCTNUM" AND "ODS_AV_SUMMARY_BYSRCCD"."SOURCECODE"(+)="MRG_QUERY"."SOURCECODE")
Note
PLAN_TABLE_OUTPUT
- dynamic sampling used for this statementHi Toon,
Thanks for the quick resolution. I went back and verified the table's colunm details and it has a NOT NULL constraint.
Regards,
Chaitanya
P.S: Is it ok if I ask you for some help regarding a production issue I have been encountering since 15 days but haev no clear resolution yet about what/why is the reason (the said issue is neither uniform nor regular - its affecting some modules and happening on some days - i shall give the full details if you are willing to have a look) - i shall start a new post or email you directly - yur convenience. -
Time column of an explain plan
Hi,
I'm using Oracle version 10.2.0.3.0. I have 2 tables with 10 million records each. The DDL is as follows.
create table bigtable(col1 varchar2(20), col2 varchar2(20))
create table bigtablechild(col1 varchar2(20), col2 varchar(20))
bigtablechild.col1 is a foreign key to bigtable.col1. Below is the query and explain plan. Over several executions, the query runs for about 20 seconds before returning results. Could anyone please explain what the time column represents? It doesn't match the time it took to return results.
SQL> set autotrace on
SQL>
SQL> select b.col2
2 from bigtable a, bigtablechild b
3 where a.col1 = b.col1
4 and a.col1 = 'ABC6554';
COL2
XYZ6554
XYZ6554
XYZ6554
XYZ6554
XYZ6554
Execution Plan
Plan hash value: 4210396901
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 5 | 150 | 21538 (4)| 00:04:19 |
|* 1 | HASH JOIN | | 5 | 150 | 21538 (4)| 00:04:19 |
|* 2 | TABLE ACCESS FULL| BIGTABLE | 1 | 10 | 13124 (4)| 00:02:38 |
|* 3 | TABLE ACCESS FULL| BIGTABLECHILD | 5 | 100 | 8413 (5)| 00:01:41 |
Predicate Information (identified by operation id):
1 - access("A"."COL1"="B"."COL1")
2 - filter("A"."COL1"='ABC6554')
3 - filter("B"."COL1"='ABC6554')
Statistics
0 recursive calls
0 db block gets
93672 consistent gets
91845 physical reads
0 redo size
463 bytes sent via SQL*Net to client
396 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
5 rows processedHi,
the values in the TIME column are calculated from cost using system I/O statistics. If dbms_stats.gather_system_stats has never been run, then these stats have default values which may be very far from the truth. In your case, the optimizer expects a single-block I/O read to take about 12 ms, while in reality it is closer to 1 ms, thus the discrepancy between the prediction and actual results.
In general, TIME column is not very helpful not just because of potentially incorrect I/O time estimates, but also because it is hard to predict how much data will be found in cash, so I would recommend not to pay too much attention to it (note, however, that A-time column, on the other hand, is extremely useful, but it's only available if rowsource statistics for the plan have been populated).
Best regards,
Nikolay
Maybe you are looking for
-
Itunes 10.6.3 - Just update to the new Itunes and the album artwork is not sticking anymore... I upload the artwork and when I change songs and go back the art is gone. Anyone with similar issue ?
-
How to stop print head cleans?
I have a B110A printer. Each time I install new ink, turn on or wake up the printer from sleep, it spends over 5 minutes doing some sort of set up. Most of all, the installation of new ink gets reduced significantly before I do any printing. This is
-
I am running Photoshop CS4 version 11.0 on a 2 x 2.66 GHz Inel Mac with OS X 10.4.11. When I save a file as a Photoshop document by choosing Save or Save As from the file menu, the document icon is a thumbnail of the image. When I save a file as a P
-
Convert to PDF in right-click menu?
Hi, I just installed Acrobat X and can't find that function which I used a lot in Acrobat 9, ie I could select several jpeg files and then click "convert to pdf" in the right click menu and now that button is gone. How do I get it back?
-
Custom non-PersistenceCapable classes used as keys in Maps and/or SortedMaps?
Hi all, I need to support custom non-PC classes as keys in SortedMaps. It takes custom coding to the Kodo API right now, and before embarking down that road, I wondered if anyone out there has already done this and is willing to share that code. Than