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,
charles
user570138 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
Similar Messages
-
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 -
Please explain plan with 'BITMAP CONVERSION TO ROWIDS'
Hi,
in my 9.2.0.8 I've got plan like :
Plan
SELECT STATEMENT CHOOSECost: 26,104
7 TABLE ACCESS BY INDEX ROWID UMOWY Cost: 26,105 Bytes: 41 Cardinality: 1
6 BITMAP CONVERSION TO ROWIDS
5 BITMAP AND
2 BITMAP CONVERSION FROM ROWIDS
1 INDEX RANGE SCAN UMW_PRD_KPD_KOD Cost: 406 Cardinality: 111,930
4 BITMAP CONVERSION FROM ROWIDS
3 INDEX RANGE SCAN UMW_PRD_KPR_KOD Cost: 13,191 Cardinality: 111,930 as far as I know Oracle is trying to combine two indexes , so if I create multicolumn index the plan should be better right ?
Generally all bitmap conversions related to b-tree indexes are trying to combine multiple indexes to deal with or/ index combine operations right ?
And finally what about AND_EQUAL hint is that kind of alternative for that bitmap conversion steps ?
Regards
Gregas far as I know Oracle is trying to combine two indexes , so if I create multicolumn index the plan should be better right ?Only you can really tell - but if this is supposed to be a "precision" query the optimizer thinks you don't have a good index into the target data. Don't forget to consider the benefits of compressed indexes if you do follow this route.
Generally all bitmap conversions related to b-tree indexes are trying to combine multiple indexes to deal with or/ index combine operations right ?Bitmap conversions when there are no real bitmap indexes involved are always about combining multiple b-tree index range scans to minimise the number of reads from the table.
And finally what about AND_EQUAL hint is that kind of alternative for that bitmap conversion steps ?AND_EQUAL was an older mechanism for combining index range scans to minimise visits to the table - it was restricted to a maximum of 5 indexes per table - the indexes had to be single column, non-unique, and the predicates had to be equality. The access method is deprecated in 10g. (See the following note, and the comments in particular, for more details: http://jonathanlewis.wordpress.com/2009/05/08/ioug-day-4/ )
Regards
Jonathan Lewis -
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 -
Oracle 11g performance issue ( BITMAP CONVERSION TO ROWIDS)
I have two instance of oracle 11g.
in both instance i fired same query.
one instance returns the result in 1sec but other instance returns the result in 10 sec
following is explain plan for bot instance
instance 1
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 143 | 59 (2)| 00:00:01 |
| 1 | HASH GROUP BY | | 1 | 143 | 59 (2)| 00:00:01 |
| 2 | VIEW | VM_NWVW_2 | 1 | 143 | 59 (2)| 00:00:01 |
| 3 | HASH UNIQUE | | 1 | 239 | 59 (2)| 00:00:01 |
| 4 | NESTED LOOPS | | | | | |
| 5 | NESTED LOOPS | | 1 | 239 | 58 (0)| 00:00:01 |
PLAN_TABLE_OUTPUT
| 6 | NESTED LOOPS | | 1 | 221 | 57 (0)| 00:00:01 |
| 7 | NESTED LOOPS | | 1 | 210 | 55 (0)| 00:00:01 |
| 8 | NESTED LOOPS | | 1 | 184 | 54 (0)| 00:00:01 |
| 9 | NESTED LOOPS | | 1 | 158 | 53 (0)| 00:00:01 |
| 10 | NESTED LOOPS | | 1 | 139 | 52 (0)| 00:00:01 |
| 11 | NESTED LOOPS | | 1 | 105 | 50 (0)| 00:00:01 |
|* 12 | INDEX RANGE SCAN | year_field | 1 | 29 | 2 (0)| 00:00:01 |
| 13 | SORT AGGREGATE | | 1 | 8 | | |
| 14 | INDEX FULL SCAN (MIN/MAX)| idx_bf_creation_date | 1 | 8 | 2 (0)| 00:00:01 |
|* 15 | TABLE ACCESS BY INDEX ROWID| OHRT_bugs_fact | 1 | 76 | 48 (0)| 00:00:01 |
|* 16 | INDEX RANGE SCAN | idx_bf_creation_date | 76 | | 1 (0)| 00:00:01 |
PLAN_TABLE_OUTPUT
|* 17 | TABLE ACCESS BY INDEX ROWID | OHRT_all_time_dimension | 1 | 34 | 2 (0)| 00:00:01 |
|* 18 | INDEX UNIQUE SCAN | unique_alltime_bug_instance_id | 1 | | 1 (0)| 00:00:01 |
| 19 | TABLE ACCESS BY INDEX ROWID | OHRT_all_time_dimension | 1 | 19 | 1 (0)| 00:00:01 |
|* 20 | INDEX UNIQUE SCAN | unique_alltime_bug_instance_id | 1 | | 1 (0)| 00:00:01 |
|* 21 | INDEX RANGE SCAN | bugseverity_instance_id_ref_id | 1 | 26 | 1 (0)| 00:00:01 |
|* 22 | INDEX UNIQUE SCAN | unique_alltime_bug_instance_id | 1 | 26 | 1 (0)| 00:00:01 |
| 23 | INLIST ITERATOR | | | | | |
|* 24 | TABLE ACCESS BY INDEX ROWID | OHMT_ANL_BUCKET | 1 | 11 | 2 (0)| 00:00:01 |
|* 25 | INDEX UNIQUE SCAN | SYS_C0053213 | 5 | | 1 (0)| 00:00:01 |
|* 26 | INDEX RANGE SCAN | FK_BUCKET_TYPE | 6 | | 0 (0)| 00:00:01 |
|* 27 | TABLE ACCESS BY INDEX ROWID | OHMT_ANL_BUCKET | 1 | 18 | 1 (0)| 00:00:01 |
instance 2
Plan
SELECT STATEMENT ALL_ROWS Cost: 22 Bytes: 142 Cardinality: 1
32 HASH GROUP BY Cost: 22 Bytes: 142 Cardinality: 1
31 VIEW VIEW SYS.VM_NWVW_2 Cost: 22 Bytes: 142 Cardinality: 1
30 HASH UNIQUE Cost: 22 Bytes: 237 Cardinality: 1
29 NESTED LOOPS
27 NESTED LOOPS Cost: 21 Bytes: 237 Cardinality: 1
25 NESTED LOOPS Cost: 20 Bytes: 219 Cardinality: 1
21 NESTED LOOPS Cost: 18 Bytes: 208 Cardinality: 1
19 NESTED LOOPS Cost: 17 Bytes: 183 Cardinality: 1
17 NESTED LOOPS Cost: 16 Bytes: 157 Cardinality: 1
14 NESTED LOOPS Cost: 15 Bytes: 138 Cardinality: 1
11 NESTED LOOPS Cost: 13 Bytes: 104 Cardinality: 1
3 INDEX RANGE SCAN INDEX REPORTSDB.year_field Cost: 2 Bytes: 29 Cardinality: 1
2 SORT AGGREGATE Bytes: 8 Cardinality: 1
1 INDEX FULL SCAN (MIN/MAX) INDEX REPORTSDB.idx_bf_creation_date Cost: 3 Bytes: 8 Cardinality: 1
10 TABLE ACCESS BY INDEX ROWID TABLE REPORTSDB.OHRT_bugs_fact Cost: 13 Bytes: 75 Cardinality: 1
9 BITMAP CONVERSION TO ROWIDS
8 BITMAP AND
5 BITMAP CONVERSION FROM ROWIDS
4 INDEX RANGE SCAN INDEX REPORTSDB.idx_OHRT_bugs_fact_2product Cost: 2 Cardinality: 85
7 BITMAP CONVERSION FROM ROWIDS
6 INDEX RANGE SCAN INDEX REPORTSDB.idx_bf_creation_date Cost: 2 Cardinality: 85
13 TABLE ACCESS BY INDEX ROWID TABLE REPORTSDB.OHRT_all_time_dimension Cost: 2 Bytes: 34 Cardinality: 1
12 INDEX UNIQUE SCAN INDEX (UNIQUE) REPORTSDB.unique_alltime_bug_instance_id Cost: 1 Cardinality: 1
16 TABLE ACCESS BY INDEX ROWID TABLE REPORTSDB.OHRT_all_time_dimension Cost: 1 Bytes: 19 Cardinality: 1
15 INDEX UNIQUE SCAN INDEX (UNIQUE) REPORTSDB.unique_alltime_bug_instance_id Cost: 1 Cardinality: 1
18 INDEX UNIQUE SCAN INDEX (UNIQUE) REPORTSDB.unique_alltime_bug_instance_id Cost: 1 Bytes: 26 Cardinality: 1
20 INDEX RANGE SCAN INDEX REPORTSDB.bugseverity_instance_id_ref_id Cost: 1 Bytes: 25 Cardinality: 1
24 INLIST ITERATOR
23 TABLE ACCESS BY INDEX ROWID TABLE OPSHUB.OHMT_ANL_BUCKET Cost: 2 Bytes: 11 Cardinality: 1
22 INDEX UNIQUE SCAN INDEX (UNIQUE) OPSHUB.SYS_C0040939 Cost: 1 Cardinality: 5
26 INDEX RANGE SCAN INDEX OPSHUB.FK_BUCKET_TYPE Cost: 0 Cardinality: 6
28 TABLE ACCESS BY INDEX ROWID TABLE OPSHUB.OHMT_ANL_BUCKET Cost: 1 Bytes: 18 Cardinality: 1
in both explain plan only difference is
9 BITMAP CONVERSION TO ROWIDS
8 BITMAP AND
5 BITMAP CONVERSION FROM ROWIDS
but is bitmap degrading performance lot?
or suggest me what other parameter i can see so 2nd instance gives me better performace.I see more differences.
In plan 1:
* 16 INDEX RANGE SCAN idx_bf_creation_date 76 1 (0) 00:00:01
in Plan 2:
1 INDEX FULL SCAN (MIN/MAX) INDEX REPORTSDB.idx_bf_creation_date Cost: 3 Bytes: 8 Cardinality: 1
So this is not about "bitmap" good/bad, it about the access strategy which changed due to differences in data statistics etc. To analyze more, I'd help a LOT if those plans would be formated in a good and same way, use around it to do so. -
[11g R2] Update-Select with BITMAP CONVERSION TO ROWIDS = very slow
Hi all,
I have to deal with some performance issues in our database.
The query below takes between 30 minutes and 60 minutes to complete (30 minutes during the batch process and 1h when I executed the query with SQLPLUS):
SQL_ID 4ky65wauhg1ub, child number 0
UPDATE fiscpt x SET (x.cimld) = (SELECT COUNT (*)
FROM fiscpt f WHERE f.comar = x.comar AND
f.coint = x.coint AND f.nucpt = x.nucpt AND
f.codev != x.codev AND f.cimvt != 0) WHERE x.comar IN
('CBOT', 'CME', 'EUREX', 'FOREX', 'LIFFE', 'METAL', 'OCC')
Plan hash value: 697684605
| Id | Operation | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time | A-Rows | A-Time | Buffers | Reads | OMem | 1Mem | Used-Mem |
| 0 | UPDATE STATEMENT | | 1 | | | 773K(100)| | 0 |00:22:22.30 | 36M| 7629 | | | |
| 1 | UPDATE | FISCPT | 1 | | | | | 0 |00:22:22.30 | 36M| 7629 | | | |
| 2 | INLIST ITERATOR | | 1 | | | | | 179K|00:00:00.37 | 1221 | 3 | | | |
|* 3 | INDEX RANGE SCAN | FISCPT1 | 7 | 154K| 4984K| 5 (0)| 00:00:01 | 179K|00:00:00.23 | 1221 | 3 | | | |
| 4 | SORT AGGREGATE | | 179K| 1 | 33 | | | 179K|01:02:58.45 | 35M| 3020 | | | |
|* 5 | TABLE ACCESS BY INDEX ROWID | FISCPT | 179K| 1 | 33 | 4 (25)| 00:00:01 | 63681 |01:02:57.80 | 35M| 3020 | | | |
| 6 | BITMAP CONVERSION TO ROWIDS | | 179K| | | | | 121K|01:02:52.71 | 35M| 885 | | | |
| 7 | BITMAP AND | | 179K| | | | | 87091 |01:02:52.25 | 35M| 885 | | | |
| 8 | BITMAP CONVERSION FROM ROWIDS| | 179K| | | | | 179K|00:00:03.31 | 241K| 0 | | | |
|* 9 | INDEX RANGE SCAN | FISCPT2 | 179K| 1547 | | 1 (0)| 00:00:01 | 1645K|00:00:02.23 | 241K| 0 | | | |
| 10 | BITMAP CONVERSION FROM ROWIDS| | 179K| | | | | 148K|01:02:44.98 | 35M| 885 | | | |
| 11 | SORT ORDER BY | | 179K| | | | | 2412M|00:52:19.70 | 35M| 885 | 1328K| 587K| 1180K (0)|
|* 12 | INDEX RANGE SCAN | FISCPT1 | 179K| 1547 | | 2 (0)| 00:00:01 | 2412M|00:22:11.22 | 35M| 885 | | | |
Query Block Name / Object Alias (identified by operation id):
1 - UPD$1
3 - UPD$1 / X@UPD$1
4 - SEL$1
5 - SEL$1 / F@SEL$1
Predicate Information (identified by operation id):
3 - access(("X"."COMAR"='CBOT' OR "X"."COMAR"='CME' OR "X"."COMAR"='EUREX' OR "X"."COMAR"='FOREX' OR "X"."COMAR"='LIFFE' OR "X"."COMAR"='METAL' OR
"X"."COMAR"='OCC'))
5 - filter("F"."CIMVT"<>0)
9 - access("F"."COINT"=:B1 AND "F"."NUCPT"=:B2)
12 - access("F"."COMAR"=:B1)
filter(("F"."CODEV"<>:B1 AND "F"."COMAR"=:B2))
Column Projection Information (identified by operation id):
2 - (upd=6; cmp=2,3,4,5) "SYS_ALIAS_4".ROWID[ROWID,10], "X"."COMAR"[VARCHAR2,5], "X"."COINT"[VARCHAR2,11], "X"."NUCPT"[VARCHAR2,8], "X"."CODEV"[VARCHAR2,3],
"X"."CIMLD"[NUMBER,22]
3 - "SYS_ALIAS_4".ROWID[ROWID,10], "X"."COMAR"[VARCHAR2,5], "X"."COINT"[VARCHAR2,11], "X"."NUCPT"[VARCHAR2,8], "X"."CODEV"[VARCHAR2,3], "X"."CIMLD"[NUMBER,22]
4 - (#keys=0) COUNT(*)[22]
5 - "F".ROWID[ROWID,10], "F"."COMAR"[VARCHAR2,5], "F"."COINT"[VARCHAR2,11], "F"."NUCPT"[VARCHAR2,8], "F"."CODEV"[VARCHAR2,3], "F"."CIMVT"[NUMBER,22]
6 - "F".ROWID[ROWID,10]
7 - STRDEF[BM VAR, 10], STRDEF[BM VAR, 10], STRDEF[BM VAR, 32496]
8 - STRDEF[BM VAR, 10], STRDEF[BM VAR, 10], STRDEF[BM VAR, 32496]
9 - "F".ROWID[ROWID,10]
10 - STRDEF[BM VAR, 10], STRDEF[BM VAR, 10], STRDEF[BM VAR, 32496]
11 - (#keys=1) "F".ROWID[ROWID,10]
12 - "F".ROWID[ROWID,10]
Note
- dynamic sampling used for this statement (level=2)We intentionally don't gather statistics on the FISCPT table.
There are no indexes on the column updated so the slowness is not due to updating of indexes:
SQL> select index_name, column_name from user_ind_columns where table_name='FISCPT';
INDEX_NAME COLUMN_NAM
FISCPT1 NUCPT
FISCPT1 CODEV
FISCPT1 RGCID
FISCPT1 DATRA
FISCPT2 COINT
FISCPT2 NUCPT
FISCPT3 NUFIS
FISCPT1 COINT
FISCPT1 COMAR
9 ligne(s) sÚlectionnÚe(s).
SQL> select count(1) from FISCPT;
COUNT(1)
179369If I replace the UPDATE-SELECT statement by a SELECT, the query runs in few seconds:
SQL> SELECT COUNT (*)
2 FROM fiscpt f, fiscpt x
3 WHERE f.comar = x.comar
4 AND f.coint = x.coint
5 AND f.nucpt = x.nucpt
6 AND f.codev != x.codev
7 AND f.cimvt != 0
8 and x.comar IN ('CBOT', 'CME', 'EUREX', 'FOREX', 'LIFFE', 'METAL', 'OCC');
COUNT(*)
63681
EcoulÚ : 00 :00 :00.75
SQL> select * from table(dbms_xplan.display_cursor());
PLAN_TABLE_OUTPUT
SQL_ID 5drbpdmdv0gv1, child number 0
SELECT COUNT (*) FROM fiscpt f, fiscpt x
WHERE f.comar = x.comar AND f.coint = x.coint
AND f.nucpt = x.nucpt AND f.codev != x.codev
AND f.cimvt != 0 and x.comar IN ('CBOT', 'CME', 'EUREX', 'FOREX',
'LIFFE', 'METAL', 'OCC')
Plan hash value: 1326101771
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | | | | 2477 (100)| |
| 1 | SORT AGGREGATE | | 1 | 53 | | | |
|* 2 | HASH JOIN | | 107K| 5557K| 4720K| 2477 (1)| 00:00:30 |
| 3 | INLIST ITERATOR | | | | | | |
|* 4 | TABLE ACCESS BY INDEX ROWID| FISCPT | 107K| 3460K| | 1674 (1)| 00:00:21 |
|* 5 | INDEX RANGE SCAN | FISCPT1 | 154K| | | 873 (0)| 00:00:11 |
|* 6 | INDEX FAST FULL SCAN | FISCPT1 | 154K| 3021K| | 337 (0)| 00:00:05 |
Predicate Information (identified by operation id):
2 - access("F"."COMAR"="X"."COMAR" AND "F"."COINT"="X"."COINT" AND
"F"."NUCPT"="X"."NUCPT")
filter("F"."CODEV"<>"X"."CODEV")
4 - filter("F"."CIMVT"<>0)
5 - access(("F"."COMAR"='CBOT' OR "F"."COMAR"='CME' OR "F"."COMAR"='EUREX' OR
"F"."COMAR"='FOREX' OR "F"."COMAR"='LIFFE' OR "F"."COMAR"='METAL' OR "F"."COMAR"='OCC'))
6 - filter(("X"."COMAR"='CBOT' OR "X"."COMAR"='CME' OR "X"."COMAR"='EUREX' OR
"X"."COMAR"='FOREX' OR "X"."COMAR"='LIFFE' OR "X"."COMAR"='METAL' OR "X"."COMAR"='OCC'))
Note
- dynamic sampling used for this statement (level=2)The optimizer parameters are at their default values.
The database is an 11.2.0.1 and the OS is a Linux Red hat.
can someone help me to tune this query please?Thanks Tubby for your reply,
We don't gather statistics at all on this table because it's a process table: on the production database we may have several processes which insert/delet/update rows into this table so we prefer to rely on Dynamic Sampling instead of gathering statistics each time a process need to access this table.
I don't dynamic sampling is the problem here because when i use the level 10 the execution plan is the same:
SQL> alter session set optimizer_dynamic_sampling=10;
Session modifiÚe.
EcoulÚ : 00 :00 :00.00
SQL> explain plan for
2 UPDATE fiscpt x
3 SET (x.cimld) =
4 (SELECT COUNT (*)
5 FROM fiscpt f
6 WHERE f.comar = x.comar
7 AND f.coint = x.coint
8 AND f.nucpt = x.nucpt
9 AND f.codev != x.codev
10 AND f.cimvt != 0)
11 WHERE x.comar IN ('CBOT', 'CME', 'EUREX', 'FOREX', 'LIFFE', 'METAL', 'OCC');
ExplicitÚ.
EcoulÚ : 00 :00 :01.04
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
Plan hash value: 697684605
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | UPDATE STATEMENT | | 179K| 5780K| 896K (20)| 02:59:23 |
| 1 | UPDATE | FISCPT | | | | |
| 2 | INLIST ITERATOR | | | | | |
|* 3 | INDEX RANGE SCAN | FISCPT1 | 179K| 5780K| 5 (0)| 00:00:01 |
| 4 | SORT AGGREGATE | | 1 | 33 | | |
|* 5 | TABLE ACCESS BY INDEX ROWID | FISCPT | 1 | 33 | 4 (25)| 00:00:01 |
| 6 | BITMAP CONVERSION TO ROWIDS | | | | | |
| 7 | BITMAP AND | | | | | |
| 8 | BITMAP CONVERSION FROM ROWIDS| | | | | |
|* 9 | INDEX RANGE SCAN | FISCPT2 | 1794 | | 1 (0)| 00:00:01 |
| 10 | BITMAP CONVERSION FROM ROWIDS| | | | | |
| 11 | SORT ORDER BY | | | | | |
|* 12 | INDEX RANGE SCAN | FISCPT1 | 1794 | | 2 (0)| 00:00:01 |
Predicate Information (identified by operation id):
3 - access("X"."COMAR"='CBOT' OR "X"."COMAR"='CME' OR "X"."COMAR"='EUREX' OR
"X"."COMAR"='FOREX' OR "X"."COMAR"='LIFFE' OR "X"."COMAR"='METAL' OR
"X"."COMAR"='OCC')
5 - filter("F"."CIMVT"<>0)
9 - access("F"."COINT"=:B1 AND "F"."NUCPT"=:B2)
12 - access("F"."COMAR"=:B1)
filter("F"."CODEV"<>:B1 AND "F"."COMAR"=:B2)
Note
- dynamic sampling used for this statement (level=10)I have tested the query you provided and the execution plan is almost the same (A FILTER clause is added but the COST isthe same):
SQL> explain plan for
2 UPDATE fiscpt x
3 SET (x.cimld) =
4 (SELECT COUNT (*)
5 FROM fiscpt f
6 WHERE f.comar = x.comar
7 AND f.coint = x.coint
8 AND f.nucpt = x.nucpt
9 AND f.codev != x.codev
10 AND f.cimvt != 0
11 and f.comar IN ('CBOT', 'CME', 'EUREX', 'FOREX', 'LIFFE', 'METAL', 'OCC')
12 )
13 WHERE x.comar IN ('CBOT', 'CME', 'EUREX', 'FOREX', 'LIFFE', 'METAL', 'OCC');
ExplicitÚ.
EcoulÚ : 00 :00 :00.01
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
Plan hash value: 1565986742
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | UPDATE STATEMENT | | 154K| 4984K| 773K (20)| 02:34:41 |
| 1 | UPDATE | FISCPT | | | | |
| 2 | INLIST ITERATOR | | | | | |
|* 3 | INDEX RANGE SCAN | FISCPT1 | 154K| 4984K| 5 (0)| 00:00:01 |
| 4 | SORT AGGREGATE | | 1 | 33 | | |
|* 5 | FILTER | | | | | |
|* 6 | TABLE ACCESS BY INDEX ROWID | FISCPT | 1 | 33 | 4 (25)| 00:00:01 |
| 7 | BITMAP CONVERSION TO ROWIDS | | | | | |
| 8 | BITMAP AND | | | | | |
| 9 | BITMAP CONVERSION FROM ROWIDS| | | | | |
|* 10 | INDEX RANGE SCAN | FISCPT2 | 1547 | | 1 (0)| 00:00:01 |
| 11 | BITMAP CONVERSION FROM ROWIDS| | | | | |
| 12 | SORT ORDER BY | | | | | |
|* 13 | INDEX RANGE SCAN | FISCPT1 | 1547 | | 2 (0)| 00:00:01 |
Predicate Information (identified by operation id):
3 - access("X"."COMAR"='CBOT' OR "X"."COMAR"='CME' OR "X"."COMAR"='EUREX' OR
"X"."COMAR"='FOREX' OR "X"."COMAR"='LIFFE' OR "X"."COMAR"='METAL' OR "X"."COMAR"='OCC')
5 - filter(:B1='CBOT' OR :B2='CME' OR :B3='EUREX' OR :B4='FOREX' OR :B5='LIFFE' OR
:B6='METAL' OR :B7='OCC')
6 - filter(("F"."COMAR"='CBOT' OR "F"."COMAR"='CME' OR "F"."COMAR"='EUREX' OR
"F"."COMAR"='FOREX' OR "F"."COMAR"='LIFFE' OR "F"."COMAR"='METAL' OR
"F"."COMAR"='OCC') AND "F"."CIMVT"<>0)
10 - access("F"."COINT"=:B1 AND "F"."NUCPT"=:B2)
13 - access("F"."COMAR"=:B1)
filter("F"."CODEV"<>:B1 AND ("F"."COMAR"='CBOT' OR "F"."COMAR"='CME' OR
"F"."COMAR"='EUREX' OR "F"."COMAR"='FOREX' OR "F"."COMAR"='LIFFE' OR
"F"."COMAR"='METAL' OR "F"."COMAR"='OCC') AND "F"."COMAR"=:B2)
Note
- dynamic sampling used for this statement (level=2)I have executed this statement for 50 minutes and it is still running now
Furthermore, I have used the tuning advisor but it has not found any recommendation.
is it normal that oracle takes 1hour to update 175k rows? -
This is the plan used for my query in my prod database.
10.2.0.3
In dev same oracle version, the plan is not doing bitmap conversion.
prod query time: 4minutes
dev query time:20 seconds
how can i tell oracle to stop bitmap conversing on me?
BTW, i have no bitmap index, weird.
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1934 | 267K| 3025 (1)| 00:00:37 |
| 1 | SORT ORDER BY | | 1934 | 267K| 3024 (25)| 00:00:37 |
| 2 | UNION-ALL | | | | | |
| 3 | MAT_VIEW ACCESS BY INDEX ROWID | MV_SONG | 92 | 14076 | 2304 (1)| 00:00:28 |
| 4 | BITMAP CONVERSION TO ROWIDS | | | | | |
| 5 | BITMAP AND | | | | | |
| 6 | BITMAP CONVERSION FROM ROWIDS| | | | | |
|* 7 | INDEX RANGE SCAN | IDX_MV_SONG_USCFALB | | | 417 (2)| 00:00:06 |
| 8 | BITMAP CONVERSION FROM ROWIDS| | | | | |
| 9 | SORT ORDER BY | | | | | |
|* 10 | DOMAIN INDEX | MV_SON_TITLE_FULLT_IDX | | | 1827 (0)| 00:00:22 |
| 11 | MAT_VIEW ACCESS BY INDEX ROWID | MV_SONG | 1842 | 253K| 720 (1)| 00:00:09 |
|* 12 | INDEX RANGE SCAN | IDXF_MV_SONG_SONTUSFALB | 737 | | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------In dev same oracle version, the plan is not doing bitmap conversion.
prod query time: 4minutes
dev query time:20 secondsIs the amount of data in both databases the same?
If you want to switch off this behaviour you can change the value of the BTREE_BITMAP_PLANS parameter. (Actually it might not be an underscore parameter in 10.2 - I wouldn't know, I'm still on 9i). Of course, the usual caveats about tweaking underscore paarmters apply.
Niall Litchfield wrote an interesting article on this pararmeter aa couple of years back. You should read it.
Cheers, APC -
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. -
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.
TIAwhen 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 -
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. -
BI-IP To track the planning changes after Data Locking
Hi All,
Need your help to design solution for one critical user requirement in IP.
We all know that in CC Planning, every month after certain date we lock the planning tool and freeze the data. But on exceptional basis, we might require to unlock planning tool to allow users to do some changes in planning data.
User wants to track these changes and report it out. Is there any standard functionality that SAP-IP has provided to track these kind of changes? If not what is the best way to achieve this?
Appreciate any input regarding this ! Thanks a lot!
SomHi,
You need to have additional characteristics for User & Date in your RTP to record who changed when and what plan record.
Then you can create a characteristic relationship of type 'Exit Class' to derive User Id(last changed by) and the date(last modified).
Itu2019s not necessary to include User-ID and Date in any of the aggregation levels, but the Source Characteristic(Company code may be in your case) based on which the values are derived for User-ID & Date, must be present in each aggregation level.
Then create a custom class say ZCL_LOC_CR_LINE_ITEM by taking class CL_RSPLS_CR_EXIT_BASE as super class and then redefine the method DERIVE of interface IF_RSPLS_CR_METHODS in your class.
You can write following code in your method DERIVE:
CLEAR e_t_mesg.
FIELD-SYMBOLS: <l_chavl> TYPE ANY.
ASSIGN COMPONENT '/BIC/ZUSERID' OF STRUCTURE c_s_chas TO <l_chavl>.
<l_chavl> = sy-uname.
ASSIGN COMPONENT '0DATE' OF STRUCTURE c_s_chas TO <l_chavl>.
<l_chavl> = sy-datlo.
This will solve your purpose.
Regards,
Deepti -
Help needed in EXPLAIN PLAN for a partitioned table
Oracle Version 9i
(Paste execution plan in a spreadsheet to make sense out of it)
I am trying to tune this query -
select * from comm c ,dates d
where
d.active_period = 'Y'
and c.period = d.period;
Operation Object Name Rows Bytes Cost Object Node In/Out PStart PStop
SELECT STATEMENT Optimizer Mode=CHOOSE 5 M 278887
HASH JOIN 5 M 5G 278887
TABLE ACCESS FULL SCHEMA.DATES 24 1 K 8
PARTITION LIST ALL 1 8
TABLE ACCESS FULL SCHEMA.COMM 6 M 5G 277624 1 8
However, I know that the dates table will return only one record. So, if I add another condition to the above query, I get this execution plan. The comm table is huge but it is partitioned on period.
select * from comm c ,dates d
where
d.active_period = 'Y'
and c.period = qd.period
and c.period = 'OCT-07'
Operation Object Name Rows Bytes Cost Object Node In/Out PStart PStop
SELECT STATEMENT Optimizer Mode=CHOOSE 1 8
MERGE JOIN CARTESIAN 1 9 K 8
TABLE ACCESS FULL SCHEMA.DATES 1 69 8
BUFFER SORT 1 9 K
TABLE ACCESS BY LOCAL INDEX ROWID SCHEMA.COMM 1 9 K 7 7
INDEX RANGE SCAN SCHEMA.COMM_NP9 1 7 7
How can I make the query such that the comm table does not have to traverse all of its partitions? The partitioning is based on quarters so it will get its data in one partition only (in the above example - partition no. 7)
Thanks in advance for writing in your replies :)You need to specify period = 'OCT-07', otherwise there is no way the optimizer can know it needs to access only one partition.
Alternatively, partition the DATES table in exactly the same way on "period", and partition-wise joins should kick in, and effectively accessing only the active partition.
Maybe you are looking for
-
What's with the semicolon 1 notation in stored procedures?
when I have a stored procedure as a data source, what is the meaning of ";1" that crystal appends to the name?
-
Best way to find and copy files
If i have a list of 2000 file names and want to find: if they exist in folder x then copy to folder y else output an error messege to txt file. What would the most efficient way to do this be? So far i've used listFiles() and put a >HUGE< directory l
-
"Today" and "Yesterday" Button is lost in Finder!!
Hi, The "Today'' and ''Yesterday'' Button in Finder is gone. It is usually shown in the ''Search For'' Drop down list but i can't find it!! Please help Cheeers
-
My users folder size is calculated at almost 13 GB. There is nothing really in there that I can tell. I noticed because I am running out of hard drive space. After trashing and emptying 7 GB worth of stuff my hard drive only regained about a gig. HEL
-
DR-2580C Scanner - Windows 8 - USB 3.0 USB Hub
I've been successfully using a DR-2580C scanner on an old Windows XP laptop for several years. I now have an Acer hybrid machine with Windows 8 Pro and a SINGLE USB 3.0 port. I'd like to use my scanner with this machine. I've installed the 2580DRIT_V