Explain Plan changed using "IN"
Hi ,
I am using one of the query as below
select a.x, b.y, c.z from a,b,c
where
a.x in ( select x from temp where col=b.y)
i checked explain plan this query is going to access full table x
i have index on x for temp table.
i need to check b.y in subquery as parameter and that subquery result i have to use as first main query's where criteria.
using function i can get only one record at time.
if anyone have any idea how to solve.
TIA
when i use = instead of "IN" below is the explain plan from TOAD
Operation Object Name Rows Bytes Cost Object Node In/Out PStart PStop
SELECT STATEMENT Optimizer Mode=RULE
SORT UNIQUE
CONCATENATION
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
TABLE ACCESS BY INDEX ROWID JOB_DETAIL_LINES
INDEX UNIQUE SCAN PK_JOT
TABLE ACCESS BY INDEX ROWID BULK_BOL
INDEX RANGE SCAN BULK_BOL_N1
TABLE ACCESS BY INDEX ROWID BULK_SKID
INDEX RANGE SCAN BULK_SKID_N1
TABLE ACCESS BY INDEX ROWID DVD_DISC_PRINT_CARTON
INDEX RANGE SCAN DVD_DISC_PRINT_CARTON_N2
TABLE ACCESS BY INDEX ROWID DVD_DISC_PRINT_SUPPLY
INDEX UNIQUE SCAN DVD_DISC_PRINT_SUPPLY_PK
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
TABLE ACCESS BY INDEX ROWID JOB_DETAIL_LINES
INDEX UNIQUE SCAN PK_JOT
TABLE ACCESS BY INDEX ROWID BULK_BOL
INDEX RANGE SCAN BULK_BOL_N1
TABLE ACCESS BY INDEX ROWID BULK_SKID
INDEX RANGE SCAN BULK_SKID_N1
TABLE ACCESS BY INDEX ROWID DVD_DISC_PRINT_CARTON
INDEX RANGE SCAN DVD_DISC_PRINT_CARTON_N2
TABLE ACCESS BY INDEX ROWID DVD_DISC_PRINT_SUPPLY
INDEX UNIQUE SCAN DVD_DISC_PRINT_SUPPLY_PK
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
TABLE ACCESS BY INDEX ROWID JOB_DETAIL_LINES
INDEX UNIQUE SCAN PK_JOT
TABLE ACCESS BY INDEX ROWID BULK_BOL
INDEX RANGE SCAN BULK_BOL_N1
TABLE ACCESS BY INDEX ROWID BULK_SKID
INDEX RANGE SCAN BULK_SKID_N1
TABLE ACCESS BY INDEX ROWID DVD_DISC_PRINT_CARTON
INDEX RANGE SCAN DVD_DISC_PRINT_CARTON_N2
TABLE ACCESS BY INDEX ROWID DVD_DISC_PRINT_SUPPLY
INDEX UNIQUE SCAN DVD_DISC_PRINT_SUPPLY_PK
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
TABLE ACCESS BY INDEX ROWID BULK_BOL
INDEX RANGE SCAN BULK_BOL_N1
TABLE ACCESS BY INDEX ROWID BULK_SKID
INDEX RANGE SCAN BULK_SKID_N1
TABLE ACCESS BY INDEX ROWID DVD_DISC_PRINT_CARTON
INDEX RANGE SCAN DVD_DISC_PRINT_CARTON_N2
TABLE ACCESS BY INDEX ROWID DVD_DISC_PRINT_SUPPLY
INDEX UNIQUE SCAN DVD_DISC_PRINT_SUPPLY_PK
TABLE ACCESS BY INDEX ROWID JOB_DETAIL_LINES
INDEX UNIQUE SCAN PK_JOT
when i use "IN" below is the explain plan from TOAD
Operation Object Name Rows Bytes Cost Object Node In/Out PStart PStop
SELECT STATEMENT Optimizer Mode=RULE
SORT UNIQUE
FILTER
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
TABLE ACCESS FULL JOB_DETAIL_LINES
TABLE ACCESS BY INDEX ROWID BULK_BOL
INDEX RANGE SCAN BULK_BOL_N1
TABLE ACCESS BY INDEX ROWID BULK_SKID
INDEX RANGE SCAN BULK_SKID_N1
TABLE ACCESS BY INDEX ROWID DVD_DISC_PRINT_CARTON
INDEX RANGE SCAN DVD_DISC_PRINT_CARTON_N2
TABLE ACCESS BY INDEX ROWID DVD_DISC_PRINT_SUPPLY
INDEX UNIQUE SCAN DVD_DISC_PRINT_SUPPLY_PK
INDEX UNIQUE SCAN PK_JOT
Similar Messages
-
Performance problem: Query explain plan changes in pl/sql vs. literal args
I have a complex query with 5+ table joins on large (million+ row) tables. In it's most simplified form, it's essentially
select * from largeTable large
join anotherLargeTable anothr on (anothr.id_2 = large.pk_id)
join...(other aux tables)
where large.pk_id between 123 and 456;
Its performance was excellent with literal arguments (1 sec per execution).
But, when I used pl/sql bind argument variables instead of 123 and 456 as literals, the explain plan changes drastically, and runs 10+ minutes.
Ex:
CREATE PROCEDURE runQuery(param1 INTEGER, param2 INTEGER){
CURSOR LT_CURSOR IS
select * from largeTable large
join anotherLargeTable anothr on (anothr.id_2 = large.pk_id)
join...(other aux tables)
where large.pk_id between param1 AND param2;
BEGIN
FOR aRecord IN LT_CURSOR
LOOP
(print timestamp...)
END LOOP;
END runQuery;
Rewriting the query 5 different ways was unfruitful. DB hints were also unfruitful in this particular case. LargeTable.pk_id was an indexed field as were all other join fields.
Solution:
Lacking other options, I wrote a literal query that concatenated the variable args. Open a cursor for the literal query.
Upside: It changed the explain plan to the only really fast option and performed at 1 second instead of 10mins.
Downside: Query not cached for future use. Perfectly fine for this query's purpose.
Other suggestions are welcome.AmandaSoosai wrote:
I have a complex query with 5+ table joins on large (million+ row) tables. In it's most simplified form, it's essentially
select * from largeTable large
join anotherLargeTable anothr on (anothr.id_2 = large.pk_id)
join...(other aux tables)
where large.pk_id between 123 and 456;
Its performance was excellent with literal arguments (1 sec per execution).
But, when I used pl/sql bind argument variables instead of 123 and 456 as literals, the explain plan changes drastically, and runs 10+ minutes.
Ex:
CREATE PROCEDURE runQuery(param1 INTEGER, param2 INTEGER){
CURSOR LT_CURSOR IS
select * from largeTable large
join anotherLargeTable anothr on (anothr.id_2 = large.pk_id)
join...(other aux tables)
where large.pk_id between param1 AND param2;
BEGIN
FOR aRecord IN LT_CURSOR
LOOP
(print timestamp...)
END LOOP;
END runQuery;
Rewriting the query 5 different ways was unfruitful. DB hints were also unfruitful in this particular case. LargeTable.pk_id was an indexed field as were all other join fields.
Solution:
Lacking other options, I wrote a literal query that concatenated the variable args. Open a cursor for the literal query.
Upside: It changed the explain plan to the only really fast option and performed at 1 second instead of 10mins.
Downside: Query not cached for future use. Perfectly fine for this query's purpose.
Other suggestions are welcome.Best wild guess based on what you've posted is a bind variable mismatch (your column is declared as a NUMBER data type and your bind variable is declared as a VARCHAR for example). Unless you have histograms on the columns in question ... which, if you're using bind variables is usually a really bad idea.
A basic illustration of my guess
http://blogs.oracle.com/optimizer/entry/how_do_i_get_sql_executed_from_an_application_to_uses_the_same_execution_plan_i_get_from_sqlplus -
9.2.0.8 on solaris 10
What are the scenarios that an explain plan will change when using RBO as optimizer_mode
we have a query like :
select * emp where empno=101;
For this query , the explain plan uses the index in the column empno where as the query :
select * emp where empno=501;
doesn't use a index . the time taken for retreival is the same . but why does the explain plan change ?.
Do we have to collect stats when using RBO ?
I tried tracing the above sessions, but couldn't find any diff (just to let you know that I tried )
Edited by: user12046873 on Feb 28, 2010 10:43 PMIt appears you are not using RBO, because using RBO would have resulted in the same execution plans. PERIOD.
Nor should you use RBO, as CBO provides way better execution plans.
You don't post these execution plans, nor how you retrieved them, so no comments are possible.
They need to be the live execution plan from a trace file,+not using explain=+ as that will have tkprof calculate the explain plan.
Sybrand Bakker
Senior Oracle DBA -
Explain plan change after partitioning - Bitmap conversion to rowid
hi gurus,
before partitioning the table using range paritioning,
for the query,
SELECT MEDIUMID
FROM MEDIUM_TB
WHERE CMREFERENCEID =8
AND CONTENTTYPEID = 8
AND CMSTATUSID = 5
AND SUBTYPEID = 99
A. before partitioning
SELECT STATEMENT, GOAL = ALL_ROWS 2452 882 16758
SORT ORDER BY 2452 882 16758
TABLE ACCESS BY INDEX ROWID DBA1 MEDIUM_TB 2451 882 16758
BITMAP CONVERSION TO ROWIDS
BITMAP AND
BITMAP CONVERSION FROM ROWIDS
INDEX RANGE SCAN DBA1 MEDIUM_TB_IX07 242 94423
BITMAP CONVERSION FROM ROWIDS
INDEX RANGE SCAN DBA1 MEDIUM_TB_IX02 1973 94423
B. after partitioning
the explain plan changed to
SELECT STATEMENT, GOAL = ALL_ROWS 33601 796 15124
TABLE ACCESS BY GLOBAL INDEX ROWID DBA1 MEDIUM_TB 33601 796 15124
INDEX RANGE SCAN DBA1 MEDIUM_TB_IX07 300 116570 as you can see in the plan, the paln cost is very high after partitioning and the query is taking more time.
index MEDIUM_TB_IX02 is not used in the second plan and also the plan method BITMAP CONVERSION.
fyi, there is all the indexes are b-tree based and global indexes.
what could be reason for the plan change?
please help
thanks,
charlesuser570138 wrote:
SELECT STATEMENT, GOAL = ALL_ROWS 2452 882 16758
SORT ORDER BY 2452 882 16758
TABLE ACCESS BY INDEX ROWID DBA1 MEDIUM_TB 2451 882 16758
BITMAP CONVERSION TO ROWIDS
BITMAP AND
BITMAP CONVERSION FROM ROWIDS
INDEX RANGE SCAN DBA1 MEDIUM_TB_IX07 242 94423
BITMAP CONVERSION FROM ROWIDS
INDEX RANGE SCAN DBA1 MEDIUM_TB_IX02 1973 94423
If you supplied proper execution plans we might be able to offer some advice.
Use dbms_xplan.
A list of the index definitions might also help
Regards
Jonathan Lewis -
Explain plan changing after partition exchange
I currently have a data warehouse where I use partition exchange to refresh the data. I'm finding that after a partition exchange of exactly the same data. explain plan changes.
database 11.2.0.2
To demonstrate what I'm doing I simplified the steps.
first I gather stats on the table that will be exchanged and run explain plan
exec dbms_stats.gather_table_stats( ownname=> 'IDW_TARGET', tabname=> 'PROGRAM_DIM' );
Select
FROM IDW_TARGET.ITD_MONTHLY_SUMMARY_FACT A,
IDW_TARGET.GL_PERIOD_DIM B,
IDW_TARGET.PROGRAM_DIM C,
IDW_TARGET.RPT_ENTITY_DIM D
WHERE ASST_SEC_CONCISE_NAME = 'abc'
AND A.GL_PERIOD_KEY = B.KEY
AND A.PROGRAM_KEY = C.KEY
AND A.RPT_ENTITY_KEY = D.KEY
AND B.PERIOD_YEAR >= 2006;
** uses FTS on fact table and runs in 20 seconds. **
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | TQ |IN-OUT| PQ Distrib |
| 0 | SELECT STATEMENT | | 25M| 71G| 47105 (1)| 00:09:26 | | | | | |
| 1 | PX COORDINATOR | | | | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10003 | 25M| 71G| 47105 (1)| 00:09:26 | | | Q1,03 | P->S | QC (RAND) |
|* 3 | HASH JOIN | | 25M| 71G| 47105 (1)| 00:09:26 | | | Q1,03 | PCWP | |
| 4 | BUFFER SORT | | | | | | | | Q1,03 | PCWC | |
| 5 | PX RECEIVE | | 4551 | 1773K| 103 (0)| 00:00:02 | | | Q1,03 | PCWP | |
| 6 | PX SEND BROADCAST | :TQ10000 | 4551 | 1773K| 103 (0)| 00:00:02 | | | | S->P | BROADCAST |
| 7 | PARTITION RANGE SINGLE | | 4551 | 1773K| 103 (0)| 00:00:02 | 1 | 1 | | | |
| 8 | TABLE ACCESS FULL | RPT_ENTITY_DIM | 4551 | 1773K| 103 (0)| 00:00:02 | 1 | 1 | | | |
|* 9 | HASH JOIN | | 25M| 61G| 46999 (1)| 00:09:24 | | | Q1,03 | PCWP | |
| 10 | BUFFER SORT | | | | | | | | Q1,03 | PCWC | |
| 11 | PX RECEIVE | | 184 | 35696 | 5 (0)| 00:00:01 | | | Q1,03 | PCWP | |
| 12 | PX SEND BROADCAST | :TQ10001 | 184 | 35696 | 5 (0)| 00:00:01 | | | | S->P | BROADCAST |
| 13 | PARTITION RANGE SINGLE | | 184 | 35696 | 5 (0)| 00:00:01 | 1 | 1 | | | |
|* 14 | TABLE ACCESS FULL | GL_PERIOD_DIM | 184 | 35696 | 5 (0)| 00:00:01 | 1 | 1 | | | |
|* 15 | HASH JOIN | | 25M| 57G| 46992 (1)| 00:09:24 | | | Q1,03 | PCWP | |
| 16 | BUFFER SORT | | | | | | | | Q1,03 | PCWC | |
| 17 | PX RECEIVE | | 4085 | 6829K| 1334 (1)| 00:00:17 | | | Q1,03 | PCWP | |
| 18 | PX SEND BROADCAST | :TQ10002 | 4085 | 6829K| 1334 (1)| 00:00:17 | | | | S->P | BROADCAST |
| 19 | PARTITION RANGE SINGLE| | 4085 | 6829K| 1334 (1)| 00:00:17 | 1 | 1 | | | |
|* 20 | TABLE ACCESS FULL | PROGRAM_DIM | 4085 | 6829K| 1334 (1)| 00:00:17 | 1 | 1 | | | |
| 21 | PX BLOCK ITERATOR | | 71M| 45G| 45650 (1)| 00:09:08 | 1 | LAST | Q1,03 | PCWC | |
| 22 | TABLE ACCESS FULL | ITD_MONTHLY_SUMMARY_FACT | 71M| 45G| 45650 (1)| 00:09:08 | 1 | 141 | Q1,03 | PCWP | |
Predicate Information (identified by operation id):
3 - access("A"."RPT_ENTITY_KEY"="D"."KEY")
9 - access("A"."GL_PERIOD_KEY"="B"."KEY")
14 - filter("B"."PERIOD_YEAR">=2006)
15 - access("A"."PROGRAM_KEY"="C"."KEY")
20 - filter("ASST_SEC_CONCISE_NAME"='abc'')
drop table PELPROGRAMDIMALLDATA; -- Start fresh here and drop the partition that will be exchanged
create table PELPROGRAMDIMALLDATA as select * from PROGRAM_DIM; -- going to use exact same data for partition exchange (only one parition)
alter table PELPROGRAMDIMALLDATA add constraint CON_342 unique ("VALUE" ) using index ;
alter table PELPROGRAMDIMALLDATA add constraint CON_343 primary key ("KEY" ) using index ;
exec dbms_stats.gather_table_stats(ownname=>'IDW_TARGET', tabname=>'PELPROGRAMDIMALLDATA');
alter table PROGRAM_DIM exchange partition ALL_DATA with table PELPROGRAMDIMALLDATA excluding indexes;
** rebuild indexes **
** explain plan for same statement uses nested loop**
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | TQ |IN-OUT| PQ Distrib |
| 0 | SELECT STATEMENT | | 2637K| 7514M| 33428 (1)| 00:06:42 | | | | | |
| 1 | PX COORDINATOR | | | | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10003 | 2637K| 7514M| 33428 (1)| 00:06:42 | | | Q1,03 | P->S | QC (RAND) |
|* 3 | HASH JOIN | | 2637K| 7514M| 33428 (1)| 00:06:42 | | | Q1,03 | PCWP | |
| 4 | BUFFER SORT | | | | | | | | Q1,03 | PCWC | |
| 5 | PX RECEIVE | | 4551 | 1773K| 103 (0)| 00:00:02 | | | Q1,03 | PCWP | |
| 6 | PX SEND BROADCAST | :TQ10000 | 4551 | 1773K| 103 (0)| 00:00:02 | | | | S->P | BROADCAST |
| 7 | PARTITION RANGE SINGLE | | 4551 | 1773K| 103 (0)| 00:00:02 | 1 | 1 | | | |
| 8 | TABLE ACCESS FULL | RPT_ENTITY_DIM | 4551 | 1773K| 103 (0)| 00:00:02 | 1 | 1 | | | |
|* 9 | HASH JOIN | | 2637K| 6511M| 33324 (1)| 00:06:40 | | | Q1,03 | PCWP | |
| 10 | BUFFER SORT | | | | | | | | Q1,03 | PCWC | |
| 11 | PX RECEIVE | | 184 | 35696 | 5 (0)| 00:00:01 | | | Q1,03 | PCWP | |
| 12 | PX SEND BROADCAST | :TQ10001 | 184 | 35696 | 5 (0)| 00:00:01 | | | | S->P | BROADCAST |
| 13 | PARTITION RANGE SINGLE | | 184 | 35696 | 5 (0)| 00:00:01 | 1 | 1 | | | |
|* 14 | TABLE ACCESS FULL | GL_PERIOD_DIM | 184 | 35696 | 5 (0)| 00:00:01 | 1 | 1 | | | |
| 15 | NESTED LOOPS | | 2642K| 6035M| 33318 (1)| 00:06:40 | | | Q1,03 | PCWP | |
| 16 | BUFFER SORT | | | | | | | | Q1,03 | PCWC | |
| 17 | PX RECEIVE | | | | | | | | Q1,03 | PCWP | |
| 18 | PX SEND ROUND-ROBIN | :TQ10002 | | | | | | | | S->P | RND-ROBIN |
| 19 | PARTITION RANGE SINGLE | | 420 | 702K| 220 (0)| 00:00:03 | 1 | 1 | | | |
| 20 | TABLE ACCESS BY LOCAL INDEX ROWID| PROGRAM_DIM | 420 | 702K| 220 (0)| 00:00:03 | 1 | 1 | | | |
|* 21 | INDEX RANGE SCAN | PROGRAM_DIM_IX20 | 420 | | 3 (0)| 00:00:01 | 1 | 1 | | | |
| 22 | PARTITION RANGE ALL | | 6299 | 4201K| 33318 (1)| 00:06:40 | 1 | 9 | Q1,03 | PCWP | |
| 23 | PARTITION LIST ALL | | 6299 | 4201K| 33318 (1)| 00:06:40 | 1 | LAST | Q1,03 | PCWP | |
| 24 | TABLE ACCESS BY LOCAL INDEX ROWID | ITD_MONTHLY_SUMMARY_FACT | 6299 | 4201K| 33318 (1)| 00:06:40 | 1 | 141 | Q1,03 | PCWP | |
| 25 | BITMAP CONVERSION TO ROWIDS | | | | | | | | Q1,03 | PCWP | |
|* 26 | BITMAP INDEX SINGLE VALUE | ITD_MONTHLY_SUMMARY_SK09 | | | | | 1 | 141 | Q1,03 | PCWP | |
Predicate Information (identified by operation id):
3 - access("A"."RPT_ENTITY_KEY"="D"."KEY")
9 - access("A"."GL_PERIOD_KEY"="B"."KEY")
14 - filter("B"."PERIOD_YEAR">=2006)
21 - access("ASST_SEC_CONCISE_NAME"='abc')
26 - access("A"."PROGRAM_KEY"="C"."KEY")
exec dbms_stats.gather_table_stats( ownname=> 'IDW_TARGET', tabname=> 'PROGRAM_DIM' );
** explain plan for same statement uses full table scan**
see first explain plan
Since the stats were not gathered after the partition exchange I would imagine that they would still be used.
Edited by: user12198207 on Feb 7, 2012 8:13 AM
Edited by: user12198207 on Feb 7, 2012 9:47 AMLocking stats did not make any difference. Also, I deleted the stats at the global level leaving just partition stats and it continued to use the nested loop which takes 15+ minutes instead of 20 seconds with the FTS.
In my original situation it listed the stats at the global level as stale after the partition exchange. But after I removed many of the steps and use just what's described in this posts.
select * from dba_tab_statistics
where table_name='PROGRAM_DIM';
shows stale stats=no for both global and partition. Kind of unexpected. Further digging in shows that is just determined by a case statement.
from dba_tab_statistics view ddl
case
when t.analyzetime is null then null
when ((m.inserts + m.deletes + m.updates) >
t.rowcnt *
to_number(DBMS_STATS.GET_PREFS('STALE_PERCENT',
u.name, o.name))/100 or
bitand(m.flags,1) = 1) then 'YES'
else 'NO'
end -
Explain plan changing for the same sql
Hi All,
In a E Business suite application, we have the 10.2.0.4 Database.
One of the program is running a select stmt which is using different explain plan one in a month which is causing issue in the program running for longer time.
Ex : When it uses the index A, it is running fine. When it uses the index B, it is running for longer time.
Can you please advice on the possible reasons for the same sql to choose index B instead of index A some times.
Thanks,
RakeshIt could be that the SQL is question got aged out of the shared pool and when it came to be reparsed - the values in the bind variables were such that access via index b was more attractive than access via index a.
Could you please send the query and the good and bad plans and all other information that might help diagnose the problem..
Note: we had a similiar case where plans suddenly changed for no apperant reason (on 10.2.0.2) - we found that under certain circumstances the optimizer would not peek into the bind varaibles to derive the execution path. -
Explain plan changes by result size from contains clause
I use 10.2.0.3 Std Edition and have a query like this
select t1.id from table1 t1
where t1.col99 = 123
and t1.id in (select ttxt.id from fulltexttable ttxt where contains (ttxt.thetext, 'word1 & word2'));
(note: for each row in table1 exists at least one corresponding row in fulltexttable)
Now I came across a surprising change in execution plans depending on the values of word1 and word2:
- if the number of result rows from the subquery is low compared to all rows the full text index is used (table access by rowid/domain index)
- if the number of result rows is high explain plan does not indicate any use of the domain index (full text index) but only a full text table scan. And the slow execution proves this plan.
But: if I create explain plan for the subquery only there is no difference whether the number of result rows is high or low: the full text index is always used.
Any clue for this change in execution strategy?
Michaelhi michael,
this is expected behaviour. because you have a query incorporating more than just a text-index, and furthermore, multiple tables, the optimizer may choose different access paths according to the cardinality of your where clause terms. in fact, anything you see is actually vanilla behaviour.
however, as i suppose, you probably have not yet heard about the "post filter" characteristic of a context index. see the tuning chapter of the text dev guide for more info. also note that the optimizer has no other way than accessing the context index directly iff you execute the subquery on its own (the "post filter" characteristic is not applicable here, because a post filter always needs some input to be filtered). and finally, be aware that oracle may unnest your subquery by its own decision, that is, do not try to force a direct context index access by a subquery, it will not work (a compiler hint is the only thing that works relyably).
the only thing i can not follow is the fts for your second example. dont you have join indexes on table1.id and fulltexttable.id, respectively?
p -
Explain plan changing between 9i and 11g
Hi
Recently we migrated the database from 9i to 11g.In 11g environment one query was running for long time and when we comapre the explain plan between 9i and 11g, we found one of the table is going through "INDEX RANGE SCAN NON UNIQUE" in 9i but in 11g it is accessing through "INDEX RANGE SCAN INDEX".
Is there any hint to add so that it will access table through "INDEX RANGE SCAN NON UNIQUE" in 11g?
Please Help.I agree with Paul.
Why are you assuming that the optimizer in 11g, which has had bug fixes and vast improvements since 9i, is optimizing the query badly just because you think the query is running slowly.
Before making assumptions, you need to find the cause of the issue, not just look for differences in two non-comparible explain plans and assume that's the cause. Adding hints to force indexes and suchlike is not the answer (even though some idiots may suggest it is).
As it says in the documentation in relation to hints:
Comments
Hints were introduced in Oracle7, when users had little recourse if the optimizer generated suboptimal plans. Now Oracle provides a number of tools, including the SQL Tuning Advisor, SQL plan management, and SQL Performance Analyzer, to help you address performance problems that are not solved by the optimizer. Oracle strongly recommends that you use those tools rather than hints. The tools are far superior to hints, because when used on an ongoing basis, they provide fresh solutions as your data and database environment change. -
SQLDeveloper can't generate an explain-plan when using "cube"
If I want to create an explain-plan from the following statement, I get no explain-plan:
SELECT 1
FROM dual
GROUP BY CUBE( 2, 2, 2, 2, 2, 2, 2, 2, 2 )If I now want to create an explain-plan again, I get the following message (and still no explain-plan):
http://i.imgur.com/mGO6Z.jpg
I tried this a few times and of course with a fresh db-session where i didn't run any statements before.
I get this with:
SQLDeveloper Version 3.0.04 Build MAIN-04.34 (i.e. production)
DB 9.2.0.1.0
Oracle Instant Client 11.1.0.6.0
In Toad this works btw.
(Of course it makes no sense to run it on this statement, we encountered this problem with a really big SQL-statement where "cube" was used in an inline-view. SQLDeveloper then wasn't able to generate an explain-plan for the whole-statement)
Regards
Markusthat is correct. I wanted to keep the login page redirect inside my class method so that I could do the check every time someone came to pages that require authentication. I wanted it in the LoadState method so I can do a check there, redirect
them to login page or just get a cookie and then pass that cookie to page to build the UI for the page
I can do what you are suggesting and have actually tried it but then I have to track which page to take the user to after they log in...
I have multiple clicks in the appbar and pages from where the user can come to these authentication-bound pages..
Suggestions?
Also, what am I doing wrong in my class method that it doesn't navigate to the login page in the LoadState method?
Thanks
mujno -
Hi All,
I have a performance issues in one of my database when i checked found that the plan has been changed.
The previous plan was good and the new plan causing the slowness in query level.
There is no code level change, No data volume increasing/ Nothing got changed in that query.
i want to reset the old plan for this query, how can we proceed with that.
is there any way to reset the old plan for the current query!!!
please help me
I dont have the query and plan details with me now, but curious to know how do we set it back with old(good) plan.
RDBMS version: Version 11.2.0.3
Edition: Enterprise Edition
OS: Linux 5.6
ThanksWhat is the cause of the plan change?
On 11.2.0.3, it might be cardinality feedback.
but curious to know how do we set it back with old(good) plan.Assuming you have the old, good plan in either the cursor cache or in AWR, then you have at least two options - one to load the plan into a sql plan baseline or to use a sql profile.
Assuming that the old plan is not in the cursor cache but is still in AWR, then the steps are along the lines of:
1. Create a SQL tuning set using DBMS_SQLTUNE.CREATE_SQLSET
2. Load in your specific plan from AWR into a SQLSET using DBMS_SQLSET.LOAD_SQLSET and DBMS_SQLTUNE.SELECT_WORKLOAD_REPOSITORY
3. Load plan into a baseline using DBMS_SPM.LOAD_PLANS_FROM_SQLSET.
Alternatively, to use a sql profile to lock in a specific plan using outline hints, see COE_XFR_SQL_PROFILE script via Oracle Support doc id 215187.1
The latter is certainly easier but baselines are marketed as sql plan management 2.0. -
Problem to create Explain Plan and use XML Indexes. Plz follow scenario..
Hi,
Oracle Version - Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit
I have been able to reproduce the error as below:
Please run the following code in Schema1:
CREATE TABLE TNAME1
DB_ID VARCHAR2 (10 BYTE),
DATA_ID VARCHAR2 (10 BYTE),
DATA_ID2 VARCHAR2 (10 BYTE),
IDENTIFIER1 NUMBER (19) NOT NULL,
ID1 NUMBER (10) NOT NULL,
STATUS1 NUMBER (10) NOT NULL,
TIME_STAMP NUMBER (19) NOT NULL,
OBJECT_ID VARCHAR2 (40 BYTE) NOT NULL,
OBJECT_NAME VARCHAR2 (80 BYTE) NOT NULL,
UNIQUE_ID VARCHAR2 (255 BYTE),
DATA_LIVE CHAR (1 BYTE) NOT NULL,
XML_MESSAGE SYS.XMLTYPE,
ID2 VARCHAR2 (255 BYTE) NOT NULL,
FLAG1 CHAR (1 BYTE) NOT NULL,
KEY1 VARCHAR2 (255 BYTE),
HEADER1 VARCHAR2 (2000 BYTE) NOT NULL,
VERSION2 VARCHAR2 (255 BYTE) NOT NULL,
TYPE1 VARCHAR2 (15 BYTE),
TIMESTAMP1 TIMESTAMP (6),
SOURCE_NUMBER NUMBER
XMLTYPE XML_MESSAGE STORE AS BINARY XML
PARTITION BY RANGE (TIMESTAMP1)
(PARTITION MAX
VALUES LESS THAN (MAXVALUE)
NOCOMPRESS
NOCACHE
ENABLE ROW MOVEMENT
begin
app_utils.drop_parameter('TNAME1_PAR');
end;
BEGIN
DBMS_XMLINDEX.REGISTERPARAMETER(
'TNAME1_PAR',
'PATH TABLE TNAME1_RP_PT
PATHS (INCLUDE ( /abc:Msg/product/productType
/abc:Msg/Products/Owner
NAMESPACE MAPPING ( xmlns:abc="Abc:Set"
END;
CREATE INDEX Indx_XPATH_TNAME1
ON "TNAME1" (XML_MESSAGE)
INDEXTYPE IS XDB.XMLINDEX PARAMETERS ( 'PARAM TNAME1_PAR' )
local;Then in Schema2, create
create synonym TNAME1 FOR SCHEMA1.TNAME1
SCHEMA1:
GRant All on TNAME1 to SCHEMA2Now in SCHEMA2, if we try:
Explain Plan for
SELECT xmltype.getclobval (XML_MESSAGE)
FROM TNAME1 t
WHERE XMLEXISTS (
'declare namespace abc="Abc:Set"; /abc:Msg/product/productType= ("1", "2") '
PASSING XML_MESSAGE);WE GET -> ORA-00942: table or view does not exist
whereas this works:
Explain Plan for
SELECT xmltype.getclobval (XML_MESSAGE)
FROM TNAME1 t- Please tell me, what is the reason behind it and how can I overcome it. It's causing all my views based on this condition to fail in another schema i.e. not picking up the XMLIndexes.
Also
SELECT * from DBA_XML_TAB_COLS WHERE TABLE_NAME like 'TNAME1';Output is like:
OWNER, || TABLE_NAME, || COLUMN_NAME, || XMLSCHEMA || SCHEMA_OWNER, || ELEMENT_NAME, || STORAGE_TYPE, || ANYSCHEMA, || NONSCHEMA
SCHEMA1 || TNAME1 || XML_MESSAGE || || || BINARY || NO || YES ||
SCHEMA1 || TNAME1 || SYS_NC00025$ || || || CLOB || ||
- Can I change AnySchema to YES from NO for -column_name = XML_MESSAGE ? May be that will solve my problem.
- SYS_NC00025$ is the XML Index, Why don't I get any values for ANYSCHEMA, NONSCHEMA on it. Is this what is causing the problem.
Kindly suggest.. Thanks..The problem sounds familiar. Please create a SR on http://support.oracle.com for this one.
-
Explain plan using v$sql_plan
Hi can I get explain plan by using v$sql_plan. I was trying to do:
select e.first_name, e.last_name, d.department_name from employees e
left join departments d on e.department_id=d.department_id;
select * from(select sql_id, hash_value from v$sql where sql_text = 'select e.first_name, e.last_name, d.department_name from employees e
left join departments d on e.department_id=d.department_id' order by last_load_time desc)where rownum=1
this select return me 0 records :(
so i cant do this :(
select operation, object_owner, object_name, object_type,options, cost, cardinality, bytes, cpu_cost, io_cost, depth from v$sql_plan where SQL_ID='value1' and HASH_VALUE='value2'
I dont know what am I doing wrongbcm@bcm-laptop:~$ sqlplus hr/hr
SQL*Plus: Release 11.2.0.1.0 Production on Tue Jul 31 11:02:04 2012
Copyright (c) 1982, 2009, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
11:02:05 SQL> set autotrace trace explain
11:02:23 SQL> select e.first_name, e.last_name, d.department_name from employees e
left join departments d on e.department_id=d.department_id;
11:02:38 2
Execution Plan
Plan hash value: 2296652067
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
|
| 0 | SELECT STATEMENT | | 107 | 3638 | 7 (15)| 00:00:01
|
|* 1 | HASH JOIN OUTER | | 107 | 3638 | 7 (15)| 00:00:01
|
| 2 | TABLE ACCESS FULL| EMPLOYEES | 107 | 1926 | 3 (0)| 00:00:01
|
| 3 | TABLE ACCESS FULL| DEPARTMENTS | 27 | 432 | 3 (0)| 00:00:01
|
Predicate Information (identified by operation id):
1 - access("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID"(+))
11:02:39 SQL> -
Explain Plan vs. V$SQL_PLAN
Hello everyone,
I'm trying to understand the difference between those two, I'm relying on the following Tom Kyte article :
http://tkyte.blogspot.com/2007/04/when-explanation-doesn-sound-quite.html
In my following example I didn't use TKPROF as he did but AUTOTRACE / V$SQL_PLAN instead (since EXPLAIN PLAN shows a theoretical plan that can be used if this statement were to be executed and V$SQL_PLAN contains the actual plan used)
That's my code :
>
HR> ALTER SYSTEM FLUSH shared_pool ;
HR>
HR> create table test
2 as
3 select a.*, 1 id
4 from all_objects a
5 where rownum = 1;
Table created.
HR>
HR> create index t_idx on test(id);
Index created.
HR>
HR> -- AUTOTRACE vs V$SQL round 1 ...
HR> ---------------------------------
HR>
HR> SET AUTOTRACE ON EXPLAIN
HR>
HR> select id, object_name from test where id = 1;
ID OBJECT_NAME
1 ICOL$
Execution Plan
Plan hash value: 2783519773
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 30 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST | 1 | 30 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | T_IDX | 1 | | 1 (0)| 00:00:01 |
Predicate Information (identified by operation id):
2 - access("ID"=1)
Note
- dynamic sampling used for this statement (level=2)
HR>
HR> SET AUTOTRACE OFF
HR>
HR>
HR> select operation, options, object_name, cost
2 from v$sql_plan
3 where hash_value= ( SELECT hash_value
4 FROM v$sqlarea
5 WHERE sql_text LIKE 'select id, object_name from test where id = 1'
6 AND sql_text NOT LIKE '%v_sql%');
OPERATION OPTIONS OBJECT_NAME COST
SELECT STATEMENT 2
TABLE ACCESS BY INDEX ROWID TEST 2
INDEX RANGE SCAN T_IDX 1
>
Ok so in round 1, the optimizer decided to get the 1 row back using Index Range Scan both in "theory" and in "reality", it make sense.
Now its time for round 2 ... :)
>
HR> insert into test select a.*, 1 from all_objects a where rownum < 1001 ;
1000 rows created.
HR>
HR> commit ;
Commit complete.
HR>
HR>
HR> -- AUTOTRACE vs V$SQL round 2 ...
HR> ---------------------------------
HR>
HR> SET AUTOTRACE ON EXPLAIN
HR>
HR> select id, object_name from test where id = 1;
ID OBJECT_NAME
1 ICOL$
1 I_VIEWTRCOL1
1001 rows selected.
Execution Plan
Plan hash value: 2783519773
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1001 | 30030 | 6 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST | 1001 | 30030 | 6 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | T_IDX | 1001 | | 5 (0)| 00:00:01 |
Predicate Information (identified by operation id):
2 - access("ID"=1)
Note
- dynamic sampling used for this statement (level=2)
HR>
HR> select operation, options, object_name, cost
2 from v$sql_plan
3 where hash_value= ( SELECT hash_value
4 FROM v$sqlarea
5 WHERE sql_text LIKE 'select id, object_name from test where id = 1'
6 AND sql_text NOT LIKE '%v_sql%');
OPERATION OPTIONS OBJECT_NAME COST
SELECT STATEMENT 2
TABLE ACCESS BY INDEX ROWID TEST 2
INDEX RANGE SCAN T_IDX 1
HR>
>
since explain plan is using always Hard Parse (and it used dynamic sampling) I would expect to see FTS in "theory"
can anyone explain me why in round 2 they both presented Index Range Scan.
Thanks ! :)Explain plan can lie, autotrace - which just does an explain plan - can lie.
See:
http://oracle-randolf.blogspot.com/2012/01/autotrace-polluting-shared-pool.html
http://kerryosborne.oracle-guy.com/2010/02/autotrace-lies/
http://hoopercharles.wordpress.com/2010/01/11/explain-plan-lies-autotrace-lies-tkprof-lies-what-is-the-plan/
V$SQL_PLAN is the truth.
You didn't mention version but DBMS_XPLAN is the most convenient way to get your plan.
If the plan is cached, inserting 1000 rows is not going to change the plan.
SQL> create table test
2 as
3 select a.*, 1 id
4 from all_objects a
5 where rownum = 1;
Table created.
SQL>
SQL> create index t_idx on test(id);
Index created.
SQL>
SQL> select id, object_name from test where id = 1;
ID OBJECT_NAME
1 ORA$BASE
SQL>
SQL> select * from table(dbms_xplan.display_cursor);
PLAN_TABLE_OUTPUT
SQL_ID 3qan6s0j3uab5, child number 0
select id, object_name from test where id = 1
Plan hash value: 2783519773
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | | | 2 (100)| |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST | 1 | 30 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | T_IDX | 1 | | 1 (0)| 00:00:01 |
Predicate Information (identified by operation id):
2 - access("ID"=1)
Note
- dynamic sampling used for this statement (level=4)
23 rows selected.
SQL> insert into test select a.*, 1 from all_objects a where rownum < 1001 ;
1000 rows created.
SQL> commit;
Commit complete.
SQL> select id, object_name from test where id = 1;
SQL> select * from table(dbms_xplan.display_cursor);
PLAN_TABLE_OUTPUT
SQL_ID 3qan6s0j3uab5, child number 0
select id, object_name from test where id = 1
Plan hash value: 2783519773
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | | | 2 (100)| |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST | 1 | 30 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | T_IDX | 1 | | 1 (0)| 00:00:01 |
Predicate Information (identified by operation id):
2 - access("ID"=1)
Note
- dynamic sampling used for this statement (level=4)
23 rows selected.
SQL> -
Explain plan - *,1 col, severals, HUH
I was wondering if someone could explain this to me. I have a simple query that joins three tables and my joins
are on the indexed columns. The stats on each of the tables are not up to date but thay are very close. (eg: stats say 950 records when there are actually 1000).
Anyway, in my query I do a select * and noticed that in the explain plan it was doing full table scans on all of the tables. So then on a whim I just selected the first column from the first table only and all of sudden the explain plan came with two of three indexes. Then when I entered in the names of all the fields of the first table the explain plan changed once again. Only this time it only used one index.
Why would what I select have any bearing on the choices
made in the explain plan. This to me makes absolutely no sense. Does it have something to do with chained or migrated records?The query is
SELECT *
FROM Families t1,
family_memberships t2,
consent_release_form t3
where t1.family_number = t2.family_number
and t2.per_id = t3.per_id
and t3.code < >'03'
In families the PK is family number
In family_membership there is a FK back to families on
family_number. Its PK is fmd_id
In consent_release_forms there is a Index on Per_id and
a PK on consent_id.
There's an intermediate table called PERSONS that slots
between family membership and the consent_release_form table that has a PK of per_id. It wasn't necessary for the query and when i added it to the query with the appropriate links it still made no difference.
WHen I just selected family number in my Select it used all the appropriate indexes because of course family number is the PK of the driving table. But still, even I selected everything why would it use a full table scan on ALL the tables. It wasn't faster. if I added a /*+ RULE */ to the query it used the correct indexes and ran twice as fast.
I just find it odd that this has been happening lately. I never used to run into situations where FTS's were used on all the tables of a query. Maybe one or two of the tables but not all. -
Why the explain plan incorrent?
I have a sql in oracle10.2.03:
select *
from (select a.*
from t_user a, t_message b
where b.user_id = a.row_id and a.user_type = 1
order by b.happen_time desc)
where rownum <= 5
there are indexes on column a.user_type,b.user_id,b.happen_time, and has been analyzed. a.user_type=1 only have 1/1000 records
the explain plan is below:
cost Cardinary Bytes
SELECT STATEMENT, GOAL = ALL_ROWS 30 5 3790
COUNT STOPKEY
VIEW BMTEST 30 6 4548
NESTED LOOPS 30 6 1158
TABLE ACCESS BY INDEX ROWID BMTEST T_MESSAGE 13 1524118 24385888
INDEX FULL SCAN DESCENDING BMTEST IDX_MESSAGE_2 1 168
TABLE ACCESS BY INDEX ROWID BMTEST T_USER 1 1 177
INDEX UNIQUE SCAN BMTEST PK_USER 1 1
Oracle use the index full scan descending on the happen_time. the cost only has 30.
After I add hint on the sql on the user_id of t_message
select *
from (select /*+index (b idx_message_1)*/ a.*
from t_user a, t_message b
where b.user_id = a.row_id and a.user_type = 1
order by b.happen_time desc)
where rownum <= 5
the explain plan change to:
cost Cardinary Bytes
SELECT STATEMENT, GOAL = ALL_ROWS 5020 5 3790
COUNT STOPKEY
VIEW BMTEST 5020 54707 41467906
SORT ORDER BY STOPKEY 5020 54707 10558451
TABLE ACCESS BY INDEX ROWID BMTEST T_MESSAGE 26 515 8240
NESTED LOOPS 2707 54707 10558451
TABLE ACCESS BY INDEX ROWID BMTEST T_USER 1 106 18762
INDEX RANGE SCAN BMTEST IDX_USER_2 1 106
INDEX RANGE SCAN BMTEST IDX_MESSAGE_1 1 515
INDEX UNIQUE SCAN BMTEST PK_USER 1 1
The cost is 5020, but the execute usage time only is 100ms, and the first SQL does not add hint usage 20s.
Why the lower cost waste more time, if the cost caculate is incorrect?
Edited by: [email protected] on Sep 11, 2008 9:14 PM[email protected] wrote:
But i am afraid i use a misunderstand title for this post,my doubt is why oracle get a large cost with the sql execute few time but get a small cost with the sql execute long time.The cost of a query isn't a particularly good proxy for runtime. It is perfectly reasonable for a query with a cost of 1000 to run more quickly than a query with a cost of 100. The cost of queries is only directly comparable between different plans in the same 10053 trace file.
[email protected] wrote:
All the indexed columns are both analyzed by the command or by DBMS_STATS package and the cpu costing is enabled.But what order are the commands being run? And why is the ANALYZE command being used to gather optimizer stats.
In the first plan:
INDEX FULL SCAN DESCENDING BMTEST IDX_MESSAGE_2 1 168
Why this index full scan cost only 1? how did oracle get this number? Is there formula to caculate the cost of index full scan? I have read the article named "Cost Based Oracle Fundamentals" and there is no introduce how to caculate it.
I think this abnormality cost makes the cost of next step "NESTED LOOPS" very smal and finally lead this abnormality result.1) Which article are you talking about? Are you talking about Jonathan Lewis's book "Cost Based Oracle Fundamentals"? Or are you referring to a different article somewhere?
2) Can you post the query plans formatted via DBMS_XPLAN.DISPLAY (including the predicate information and enclose the output in the \[pre\] and \[pre\] tags to preserve white space?
Justin
Justin
Maybe you are looking for
-
I have a new mac mini, do I have enough space to download Windows 7, and can I do it through online purchase or disc? My bootcamp assistant mentions using a USB flash drive???
-
hello i managed to use the Set Language Portlet well, however, when i click the set language portlet the following Action is called http://address:7777/orasso/orasso.wwctx_app_language my client is not happy about opening port 7777, how can we instru
-
Set color alv output cell abap webdynpro
Hi Guys , i wanted to set the color of some cells in alv output to red in ABAP WebDynpro. i am using the salv_wd_table. any piece of code is appreciated. thanks, Bobby.
-
V5.0 software update for Blackberry Curve 8530
I updated my virgin mobile blackberry curve 8530 to the v5.0 software update , but the sms text DOES NOT look anything like the BBM chat. It hasn't changed at all from the last version . That's the whole reason why I updated it. Please help . Thank y
-
Help! Airport Express for PC not recognized
I'm trying to connect a PC to airport express to use augioengine 5A speakers via wireless. I've installed the airport software on the PC, plugged in the airport to the wall outlet, and opened AirPort Utility, but the screen is stuck on scanning. It c