EXPLAIN PLAN estimate is WAY off!
I used Explain Plan to estimate the time it will take to run a SQL query.
This is the query:
select to_char (a.calldate,'yyyy')as "date", a.CALL_TYPE_ABBR_NAME, b.name, sum(a.call_price) as "monthly revenue"
from allcalls a, call_types b
where a.CALL_TYPE_ABBR_NAME= b.code
group by to_char (a.calldate,'yyyy'), a.CALL_TYPE_ABBR_NAME, b.name
order by to_char (a.calldate,'yyyy'),a.CALL_TYPE_ABBR_NAME, b.name;
allcalls table has 12,669,348 records and call_types has only 3.
Both tables have been analyzed.
The query actually takes only 2 minutes and 21 seconds to complete execution.
But according to EXPLAIN PLAN and SELECT plan_table_output FROM table(dbms_xplan.display) it will take 2 hours. The output of the table(dbms_xplan.display) is:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD></HEAD>
<BODY><!--StartFragment--><TABLE>
<TBODY>
<TR bgcolor=#afafaf>
<TD><B>PLAN_TABLE_OUTPUT</B></TD></TR><TR>
<TD>Plan hash value: 3083213950</TD>
</TR>
<TR>
<TD> </TD>
</TR>
<TR>
<TD>------------------------------------------------------------------------------------------</TD>
</TR>
<TR>
<TD>| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |</TD>
</TR>
<TR>
<TD>------------------------------------------------------------------------------------------</TD>
</TR>
<TR>
<TD>| 0 | SELECT STATEMENT | | 12M| 241M| | 215K (1)| 00:43:05 |</TD>
</TR>
<TR>
<TD>| 1 | SORT GROUP BY | | 12M| 241M| 776M| 215K (1)| 00:43:05 |</TD>
</TR>
<TR>
<TD>|* 2 | HASH JOIN | | 12M| 241M| | 138K (1)| 00:27:40 |</TD>
</TR>
<TR>
<TD>| 3 | TABLE ACCESS FULL| CALL_TYPES | 3 | 30 | | 3 (0)| 00:00:01 |</TD>
</TR>
<TR>
<TD>| 4 | TABLE ACCESS FULL| ALLCALLS | 12M| 120M| | 138K (1)| 00:27:39 |</TD>
</TR>
<TR>
<TD>------------------------------------------------------------------------------------------</TD>
</TR>
<TR>
<TD> </TD>
</TR>
<TR>
<TD>Predicate Information (identified by operation id):</TD>
</TR>
<TR>
<TD>---------------------------------------------------</TD>
</TR>
<TR>
<TD> </TD>
</TR>
<TR>
<TD> 2 - access("A"."CALL_TYPE_ABBR_NAME"="B"."CODE")</TD>
</TR>
</TBODY></TABLE><!--EndFragment--></BODY>
</HTML>
So, it's basically useless to rely on EXPLAIN PLAIN to estimate the time it will take to run a query? Or is there something else we can do to get the estimate better?
Hello Channa,
You are really going about this thing the wrong way... but... you have amused a few :)
As you've been told (a number of times and, a number of different ways :) ) any attempt at pegging the execution time of a SQL statement is quite futile and rather irrelevant to boot.
This is what I suggest you do:
1. Whatever application you are selling, it must handle a certain volume of data. Since I don't know anything about the application you're selling, I'm going to give you an example while pulling numbers out of my magic hat ;) . Let's presume that your application should handle reasonably well 12,000,000 rows spread across 100 tables and, that there are a number of reports that are run with greater frequency than others. (since you know your application, you'll need to adjust these numbers for whatever are representative numbers for your app).
1.1 As an aside, I would not tell a prospective customer that you've tested the system using 14 rows. That could turn a few of them off ;) In other words, would you buy a database product from anyone that told you "Oh yeah! we tested it with 14 rows, it did great! ... runs like champ!" ? probably not. That's why you need larger numbers as pointed out in 1. above.
2. Once you have a setup with a reasonable number of rows ;) you run whatever reports are important to your customers and you time them. The timings don't have to be exact, they'll vary but, everything being kept equal, the variation won't be as dramatic as using 14 rows ;)
2.1 Given a reasonable test sample - meaning: more rows than there are donuts in a cop's car at 7:00 a.m - you customarily throw away the best and worst run times because those are often not representative.
2.2 You compute an average and a standard deviation (this is not hard to do)
2.3 You tell your customers that in order to get similar results to what you've presented they need xyz hardware configuration. In other words, you qualify the environment in which those results can be obtained.
If someone asks for an exact figure, you tell them that there are refreshments on the table ;) or, if you are so inclined, you explain that exact is not possible.
HTH,
John.
Similar Messages
-
Explain plan cardinallity is way off compared to actual rows being returned
Database version 11.2.0.3
We have a small but rapidly growing datawarehouse which has OBIEE as its front end reporting tool. Our DBA has set up a automatic stats gathering method in OEM and we can see that it run and gathers stats on stale objects on a regular basis. So we know the statistics are upto date.
In checking some slow queries I can see that the cardinality being reported in explain plans is way off compared to what is actually being returned.
For example the actual number of rows returned are 8000 but the cardinality estimate is > 300,000.
Now as per an Oracle White paper(The Oracle Optimizer Explain the Explain Plan) having "multiple single column predicates on a single table" can affect cardinality estimates and in case of our query that is true. Here is the "WHERE Clause section" of the query
SQL> select D1.c1 as c1,
2 D1.c2 as c2,
3 D1.c3 as c3,
4 D1.c4 as c4,
5 D1.c5 as c5,
6 D1.c6 as c6,
7 D1.c7 as c7,
8 D1.c8 as c8,
9 D1.c9 as c9,
10 D1.c10 as c10,
11 D1.c11 as c11,
12 D1.c12 as c12,
13 D1.c13 as c13,
14 D1.c14 as c14,
15 D1.c15 as c15,
16 D1.c16 as c16
17 from (select D1.c4 as c1,
18 D1.c5 as c2,
19 D1.c3 as c3,
20 D1.c1 as c4,
21 D1.c6 as c5,
22 D1.c7 as c6,
23 D1.c2 as c7,
24 D1.c8 as c8,
25 D1.c9 as c9,
26 D1.c10 as c10,
27 D1.c9 as c11,
28 D1.c11 as c12,
29 D1.c2 as c13,
30 D1.c2 as c14,
31 D1.c12 as c15,
32 'XYZ' as c16,
33 ROW_NUMBER() OVER(PARTITION BY D1.c2, D1.c3, D1.c4, D1.c5, D1.c6, D1.c7, D1.c8, D1.c9, D1.c10, D1.c11, D1.c12 ORDER BY D1.c2 ASC, D1.c3 ASC, D1.c4 ASC, D1.c5 ASC, D1.c6 ASC, D1.c
ASC, D1.c8 ASC, D1.c9 ASC, D1.c10 ASC, D1.c11 ASC, D1.c12 ASC) as c17
34 from (select distinct D1.c1 as c1,
35 D1.c2 as c2,
36 'CHANNEL1' as c3,
37 D1.c3 as c4,
38 D1.c4 as c5,
39 D1.c5 as c6,
40 D1.c6 as c7,
41 D1.c7 as c8,
42 D1.c8 as c9,
43 D1.c9 as c10,
44 D1.c10 as c11,
45 D1.c11 as c12
46 from (select sum(T610543.GLOBAL1_EXCHANGE_RATE * case
47 when T610543.X_ZEB_SYNC_EBS_FLG = 'Y' then
48 T610543.X_ZEB_AIA_U_REVN_AMT
49 else
50 0
51 end) as c1,
52 T536086.X_ZEBRA_TERRITORY as c2,
53 T526821.LEVEL9_NAME as c3,
54 T526821.LEVEL1_NAME as c4,
55 T577698.PER_NAME_FSCL_YEAR as c5,
56 T577698.FSCL_QTR as c6,
57 T31796.X_ZEBRA_TERRITORY as c7,
58 T31796.X_OU_NUM as c8,
59 T664055.TERRITORY as c9,
60 T536086.X_OU_NUM as c10,
61 T526821.LEVEL4_NAME as c11
62 from W_INT_ORG_D T613144 /* Dim_ZEB_W_INT_ORG_D_POS_Client_Attr_Direct */,
63 W_ZEBRA_REGION_D T664055 /* Dim_ZEB_W_ZEBRA_REGION_D_POS_Client_Direct */,
64 W_DAY_D T577698 /* Dim_ZEB_W_DAY_D_Order_Invoice_Date */,
65 WC_PRODUCT_HIER_DH T526821 /* Dim_WC_PRODUCT_HIER_DH */,
66 W_PRODUCT_D T32069 /* Dim_W_PRODUCT_D */,
67 W_ORG_D T31796,
68 W_ORG_D T536086 /* Dim_ZEB_W_ORG_D_Reseller */,
69 W_ORDERITEM_TMP_F T610543 /* Fact_ZEB_W_ORDERITEM_F_Direct */
70 where (T610543.PR_OWNER_BU_WID = T613144.ROW_WID and
71 T577698.ROW_WID =
72 T610543.X_ZEB_AIA_TRXN_DT_WID and
73 T32069.ROW_WID = T526821.PROD_WID and
74 T32069.ROW_WID = T610543.ROOT_LN_PROD_WID and
75 T536086.ROW_WID = T610543.ACCNT_WID and
76 T31796.DATASOURCE_NUM_ID =
77 T610543.DATASOURCE_NUM_ID and
78 T31796.INTEGRATION_ID = T610543.VIS_PR_BU_ID and
79 T536086.DELETE_FLG = 'N' and
80 T610543.X_ZEB_DELETE_FLG = 'N' and
81 T613144.X_ZEB_REGION_WID = T664055.ROW_WID and
82 T577698.FSCL_DAY_OF_YEAR < 97 and
83 '2006' < T577698.PER_NAME_FSCL_YEAR and
84 T536086.X_OU_NUM <> '11073' and
85 T536086.X_ZEBRA_TERRITORY !=
86 'XX23' and
87 T536086.X_OU_NUM != '56791647728774' and
88 T536086.X_OU_NUM != '245395890' and
89 T536086.X_ZEBRA_TERRITORY !=
90 'STRATEGIC ACCTS 2' and
91 T526821.LEVEL2_NAME != 'Charges' and
92 T526821.LEVEL9_NAME != 'Unspecified' and
93 T536086.X_ZEBRA_TERRITORY !=
94 'XX1' and T536086.X_ZEBRA_TERRITORY !=
95 'XX2' and T536086.X_ZEBRA_TERRITORY !=
96 'XX3' and T536086.X_ZEBRA_TERRITORY !=
97 'XX4' and
98 (T536086.X_ZEBRA_TERRITORY in
99 ( ... In List of 22 values )) and
125 T32069.X_ZEB_EBS_PRODUCT_TYPE is null)
126 group by T31796.X_ZEBRA_TERRITORY,
127 T31796.X_OU_NUM,
128 T526821.LEVEL1_NAME,
129 T526821.LEVEL4_NAME,
130 T526821.LEVEL9_NAME,
131 T536086.X_OU_NUM,
132 T536086.X_ZEBRA_TERRITORY,
133 T577698.FSCL_QTR,
134 T577698.PER_NAME_FSCL_YEAR,
135 T664055.TERRITORY) D1) D1) D1
136 where (D1.c17 = 1)
137 /
Elapsed: 00:00:35.19
Execution Plan
Plan hash value: 3285002974
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | Pstart| Pstop | TQ |IN-OUT| PQ Distrib |
| 0 | SELECT STATEMENT | | 2145M| 2123G| | 612K (1)| 03:03:47 | | | | | |
| 1 | PX COORDINATOR | | | | | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10012 | 2145M| 2123G| | 612K (1)| 03:03:47 | | | Q1,12 | P->S | QC (RAND) |
|* 3 | VIEW | | 2145M| 2123G| | 612K (1)| 03:03:47 | | | Q1,12 | PCWP | |
|* 4 | WINDOW NOSORT | | 2145M| 421G| | 612K (1)| 03:03:47 | | | Q1,12 | PCWP | |
| 5 | SORT GROUP BY | | 2145M| 421G| 448G| 612K (1)| 03:03:47 | | | Q1,12 | PCWP | |
| 6 | PX RECEIVE | | 2145M| 421G| | 1740 (11)| 00:00:32 | | | Q1,12 | PCWP | |
| 7 | PX SEND HASH | :TQ10011 | 2145M| 421G| | 1740 (11)| 00:00:32 | | | Q1,11 | P->P | HASH |
|* 8 | HASH JOIN BUFFERED | | 2145M| 421G| | 1740 (11)| 00:00:32 | | | Q1,11 | PCWP | |
| 9 | PX RECEIVE | | 268K| 7864K| | 93 (2)| 00:00:02 | | | Q1,11 | PCWP | |
| 10 | PX SEND HASH | :TQ10009 | 268K| 7864K| | 93 (2)| 00:00:02 | | | Q1,09 | P->P | HASH |
| 11 | PX BLOCK ITERATOR | | 268K| 7864K| | 93 (2)| 00:00:02 | | | Q1,09 | PCWC | |
| 12 | TABLE ACCESS FULL | W_ORG_D | 268K| 7864K| | 93 (2)| 00:00:02 | | | Q1,09 | PCWP | |
| 13 | PX RECEIVE | | 345K| 59M| | 1491 (2)| 00:00:27 | | | Q1,11 | PCWP | |
| 14 | PX SEND HASH | :TQ10010 | 345K| 59M| | 1491 (2)| 00:00:27 | | | Q1,10 | P->P | HASH |
|* 15 | HASH JOIN BUFFERED | | 345K| 59M| | 1491 (2)| 00:00:27 | | | Q1,10 | PCWP | |
| 16 | PX RECEIVE | | 1321 | 30383 | | 2 (0)| 00:00:01 | | | Q1,10 | PCWP | |
| 17 | PX SEND BROADCAST | :TQ10006 | 1321 | 30383 | | 2 (0)| 00:00:01 | | | Q1,06 | P->P | BROADCAST |
| 18 | PX BLOCK ITERATOR | | 1321 | 30383 | | 2 (0)| 00:00:01 | | | Q1,06 | PCWC | |
| 19 | TABLE ACCESS FULL | W_ZEBRA_REGION_D | 1321 | 30383 | | 2 (0)| 00:00:01 | | | Q1,06 | PCWP | |
|* 20 | HASH JOIN | | 345K| 52M| | 1488 (2)| 00:00:27 | | | Q1,10 | PCWP | |
| 21 | JOIN FILTER CREATE | :BF0000 | 9740 | 114K| | 2 (0)| 00:00:01 | | | Q1,10 | PCWP | |
| 22 | PX RECEIVE | | 9740 | 114K| | 2 (0)| 00:00:01 | | | Q1,10 | PCWP | |
| 23 | PX SEND HASH | :TQ10007 | 9740 | 114K| | 2 (0)| 00:00:01 | | | Q1,07 | P->P | HASH |
| 24 | PX BLOCK ITERATOR | | 9740 | 114K| | 2 (0)| 00:00:01 | | | Q1,07 | PCWC | |
| 25 | TABLE ACCESS FULL | W_INT_ORG_D | 9740 | 114K| | 2 (0)| 00:00:01 | | | Q1,07 | PCWP | |
| 26 | PX RECEIVE | | 344K| 47M| | 1486 (2)| 00:00:27 | | | Q1,10 | PCWP | |
| 27 | PX SEND HASH | :TQ10008 | 344K| 47M| | 1486 (2)| 00:00:27 | | | Q1,08 | P->P | HASH |
| 28 | JOIN FILTER USE | :BF0000 | 344K| 47M| | 1486 (2)| 00:00:27 | | | Q1,08 | PCWP | |
|* 29 | HASH JOIN BUFFERED | | 344K| 47M| | 1486 (2)| 00:00:27 | | | Q1,08 | PCWP | |
| 30 | JOIN FILTER CREATE | :BF0001 | 35290 | 964K| | 93 (2)| 00:00:02 | | | Q1,08 | PCWP | |
| 31 | PX RECEIVE | | 35290 | 964K| | 93 (2)| 00:00:02 | | | Q1,08 | PCWP | |
| 32 | PX SEND HASH | :TQ10004 | 35290 | 964K| | 93 (2)| 00:00:02 | | | Q1,04 | P->P | HASH |
| 33 | PX BLOCK ITERATOR | | 35290 | 964K| | 93 (2)| 00:00:02 | | | Q1,04 | PCWC | |
|* 34 | TABLE ACCESS FULL | W_ORG_D | 35290 | 964K| | 93 (2)| 00:00:02 | | | Q1,04 | PCWP | |
| 35 | PX RECEIVE | | 344K| 38M| | 1392 (2)| 00:00:26 | | | Q1,08 | PCWP | |
| 36 | PX SEND HASH | :TQ10005 | 344K| 38M| | 1392 (2)| 00:00:26 | | | Q1,05 | P->P | HASH |
| 37 | JOIN FILTER USE | :BF0001 | 344K| 38M| | 1392 (2)| 00:00:26 | | | Q1,05 | PCWP | |
|* 38 | HASH JOIN BUFFERED | | 344K| 38M| | 1392 (2)| 00:00:26 | | | Q1,05 | PCWP | |
| 39 | PX RECEIVE | | 93791 | 4671K| | 7 (0)| 00:00:01 | | | Q1,05 | PCWP | |
| 40 | PX SEND HASH | :TQ10001 | 93791 | 4671K| | 7 (0)| 00:00:01 | | | Q1,01 | P->P | HASH |
| 41 | PX BLOCK ITERATOR | | 93791 | 4671K| | 7 (0)| 00:00:01 | | | Q1,01 | PCWC | |
|* 42 | TABLE ACCESS FULL | WC_PRODUCT_HIER_DH | 93791 | 4671K| | 7 (0)| 00:00:01 | | | Q1,01 | PCWP | |
|* 43 | HASH JOIN | | 894K| 57M| | 1384 (2)| 00:00:25 | | | Q1,05 | PCWP | |
| 44 | JOIN FILTER CREATE | :BF0002 | 243K| 1904K| | 48 (3)| 00:00:01 | | | Q1,05 | PCWP | |
| 45 | PX RECEIVE | | 243K| 1904K| | 48 (3)| 00:00:01 | | | Q1,05 | PCWP | |
| 46 | PX SEND HASH | :TQ10002 | 243K| 1904K| | 48 (3)| 00:00:01 | | | Q1,02 | P->P | HASH |
| 47 | PX BLOCK ITERATOR | | 243K| 1904K| | 48 (3)| 00:00:01 | | | Q1,02 | PCWC | |
|* 48 | TABLE ACCESS FULL | W_PRODUCT_D | 243K| 1904K| | 48 (3)| 00:00:01 | | | Q1,02 | PCWP | |
| 49 | PX RECEIVE | | 894K| 50M| | 1336 (2)| 00:00:25 | | | Q1,05 | PCWP | |
| 50 | PX SEND HASH | :TQ10003 | 894K| 50M| | 1336 (2)| 00:00:25 | | | Q1,03 | P->P | HASH |
| 51 | JOIN FILTER USE | :BF0002 | 894K| 50M| | 1336 (2)| 00:00:25 | | | Q1,03 | PCWP | |
|* 52 | HASH JOIN | | 894K| 50M| | 1336 (2)| 00:00:25 | | | Q1,03 | PCWP | |
| 53 | PX RECEIVE | | 292 | 3504 | | 136 (0)| 00:00:03 | | | Q1,03 | PCWP | |
| 54 | PX SEND BROADCAST LOCAL| :TQ10000 | 292 | 3504 | | 136 (0)| 00:00:03 | | | Q1,00 | P->P | BCST LOCAL |
| 55 | PX BLOCK ITERATOR | | 292 | 3504 | | 136 (0)| 00:00:03 | | | Q1,00 | PCWC | |
|* 56 | TABLE ACCESS FULL | W_DAY_D | 292 | 3504 | | 136 (0)| 00:00:03 | | | Q1,00 | PCWP | |
| 57 | PX BLOCK ITERATOR | | 4801K| 215M| | 1199 (2)| 00:00:22 | 1 | 11 | Q1,03 | PCWC | |
|* 58 | TABLE ACCESS FULL | W_ORDERITEM_TMP_F | 4801K| 215M| | 1199 (2)| 00:00:22 | 1 | 44 | Q1,03 | PCWP | |
Note
- dynamic sampling used for this statement (level=5)
Statistics
498 recursive calls
2046 db block gets
1193630 consistent gets
74398 physical reads
0 redo size
655170 bytes sent via SQL*Net to client
11761 bytes received via SQL*Net from client
541 SQL*Net roundtrips to/from client
64 sorts (memory)
0 sorts (disk)
8090 rows processed
SQL>So my question is if, cardinality estimates are way off, is that an indicator that the explain plans being generated are sub-optimal?
Can you provide me with some tips or links to blog post or books on how I approach tuning such queries where cardinalities are not good?
Edited by: qqq on Apr 7, 2013 2:27 PMAs already asked in your other thread:
Please see the FAQ for how to post a tuning request and the information that you need to provide.
Part of that information is:
1. DDL for the table and indexes
2. The query being used
3. row counts for the table and for the predicates used in the query
4. info about stats. You did update the table and index stats didn't you?
5. The 'actual' execution plans.
An explain plan just shows what Oracle 'thinks' it is going to do. The actual plans show what Oracle actually 'did' do. Just because Oracle expected to save doesn't mean the savings were actually achieved.
When you post the plans use on the line before and on the line after to preserve formatting.
Your partial code is virtually unusable because of the missing conditions in the predicates. You need to use '!=' for 'not equals' if that's what those missing conditions are.
Please edit your post to use code tags, add the missing conditions and provide the other information needed for a tuning request. -
Hi,
Is there any relationship between the cost factor in the explain plan and query execution time. I have come across situations in both ways, i.e. high cost and low execution time, low cost and high execution time. What parameters do we need to consider in tuning a query high cost or low cost?So my assumption is that the lower cost does not guarantee faster response time. Again i have have seen many people try to reduce the cost first.Can anyone help me on this issue please.
Thanks-BhaskarCost is a metric that Oracle uses to estimate the runtime of a query. However, it is not something that you probably ought to pay a lot of attention to. If you are looking at the performance of a query, you are presumably operating on the assumption that the optimizer may have chosen an incorrect plan. If the optimizer chose an incorrect plan then by definition the cost is incorrect. If the cost is correct then, by definition, Oracle chose the correct plan.
It makes much more sense to focus on things like the cardinality of each step (the number of rows each step in the plan is expected to return). If the cardinality estimates are correct (or reasonably close), then the optimizer probably chose the correct plan. If the cardinality estimates are way off, the optimizer probably chose a less than optimal plan. And when you find the first step where the cardinality estimates are wildly incorrect, you'll know where you need to start focusing your tuning efforts.
Justin -
Explain plans differ: same query, cloned databases.
oracle 10.2.0.2.0
solaris 10
same query, different databases (cloned from same source), different explain plans.
db parameters are identical.
Any ideas?
DB1 (production)
SQL> explain plan for
2 SELECT V__101.*, SHAPE.fid,SHAPE.numofpts,SHAPE.entity,SHAPE.points,
3 SHAPE.rowid
4 FROM
5 (SELECT b.OBJECTID,b.CRT_DTE,b.CRT_SRC_CDE,b.CRT_AQUI_MTHD_CDE,b.CRT_USR_ID,
6 b.ADT_ACTN_CDE,b.ADT_ACTN_DTE,b.ADT_ACTN_SRC_CDE,b.ADT_ACTN_USR_ID,
7 b.TP_SITE_POINT_ID,b.SHAPE,b.SRC_ID,b.SRC_CRT_DTE,b.SRC_TYPE_CDE,
8 b.LCTN_STAT_CDE,b.FRZN_LCTN_IND,b.TP_NOTES FROM AMSOWNER.TP_SITE_POINT b
9 WHERE b.OBJECTID NOT IN (SELECT /*+ HASH_AJ */ SDE_DELETES_ROW_ID FROM
10 AMSOWNER.D101 WHERE DELETED_AT IN (SELECT l.lineage_id FROM
SDE.state_lineages l WHERE l.lineage_name = :source_lineage_name AND
11 12 l.lineage_id <= :source_state_id) AND SDE_STATE_ID = :"SYS_B_0") UNION ALL
SELECT a.OBJECTID,a.CRT_DTE,a.CRT_SRC_CDE,a.CRT_AQUI_MTHD_CDE,a.CRT_USR_ID,
13 14 a.ADT_ACTN_CDE,a.ADT_ACTN_DTE,a.ADT_ACTN_SRC_CDE,a.ADT_ACTN_USR_ID,
15 a.TP_SITE_POINT_ID,a.SHAPE,a.SRC_ID,a.SRC_CRT_DTE,a.SRC_TYPE_CDE,
16 a.LCTN_STAT_CDE,a.FRZN_LCTN_IND,a.TP_NOTES FROM AMSOWNER.A101 a,
17 SDE.state_lineages SL WHERE (a.OBJECTID, a.SDE_STATE_ID) NOT IN (SELECT /*+
18 HASH_AJ */ SDE_DELETES_ROW_ID,SDE_STATE_ID FROM AMSOWNER.D101 WHERE
19 DELETED_AT IN (SELECT l.lineage_id FROM SDE.state_lineages l WHERE
20 l.lineage_name = :source_lineage_name AND l.lineage_id <= :source_state_id)
21 AND SDE_STATE_ID > :"SYS_B_1") AND a.SDE_STATE_ID = SL.lineage_id AND
22 SL.lineage_name = :source_lineage_name AND SL.lineage_id <=
23 :source_state_id ) V__101 , AMSOWNER.F15 SHAPE where SHAPE.FID(+) =
24 V__101.SHAPE;
Explained.
SQL> @?/rdbms/admin/utlxplp.sql;
PLAN_TABLE_OUTPUT
Plan hash value: 254376361
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 113K| 49M| | 2926 (1)| 00:00:41 |
|* 1 | HASH JOIN RIGHT OUTER | | 113K| 49M| 17M| 2926 (1)| 00:00:41 |
| 2 | TABLE ACCESS FULL | F15 | 113K| 15M| | 344 (2)| 00:00:05 |
| 3 | VIEW | | 113K| 34M| | 331 (2)| 00:00:05 |
| 4 | UNION-ALL | | | | | | |
|* 5 | HASH JOIN RIGHT ANTI | | 113K| 8948K| | 332 (2)| 00:00:05 |
| 6 | VIEW | VW_NSO_1 | 1 | 13 | | 2 (0)| 00:00:01 |
| 7 | NESTED LOOPS | | 1 | 50 | | 2 (0)| 00:00:01 |
| 8 | TABLE ACCESS BY INDEX ROWID| D101 | 1 | 39 | | 1 (0)| 00:00:01 |
|* 9 | INDEX SKIP SCAN | D101_IDX1 | 1 | | | 1 (0)| 00:00:01 |
|* 10 | INDEX UNIQUE SCAN | LINEAGES_PK | 1 | 11 | | 1 (0)| 00:00:01 |
| 11 | TABLE ACCESS FULL | TP_SITE_POINT | 113K| 7512K| | 329 (2)| 00:00:05 |
|* 12 | HASH JOIN ANTI | | 1 | 375 | | 5 (20)| 00:00:01 |
| 13 | NESTED LOOPS | | 1 | 349 | | 2 (0)| 00:00:01 |
| 14 | TABLE ACCESS BY INDEX ROWID | A101 | 1 | 338 | | 1 (0)| 00:00:01 |
|* 15 | INDEX RANGE SCAN | A101_STATEID_IX1 | 1 | | | 1 (0)| 00:00:01 |
|* 16 | INDEX UNIQUE SCAN | LINEAGES_PK | 1 | 11 | | 1 (0)| 00:00:01 |
|* 17 | VIEW | VW_NSO_2 | 1 | 26 | | 2 (0)| 00:00:01 |
| 18 | NESTED LOOPS | | 1 | 50 | | 2 (0)| 00:00:01 |
|* 19 | INDEX FULL SCAN | D101_PK | 1 | 39 | | 1 (0)| 00:00:01 |
|* 20 | INDEX UNIQUE SCAN | LINEAGES_PK | 1 | 11 | | 1 (0)| 00:00:01 |
Predicate Information (identified by operation id):
1 - access("SHAPE"."FID"(+)="V__101"."SHAPE")
5 - access("B"."OBJECTID"="$nso_col_1")
9 - access("SDE_STATE_ID"=TO_NUMBER(:SYS_B_0))
filter("SDE_STATE_ID"=TO_NUMBER(:SYS_B_0))
10 - access("L"."LINEAGE_NAME"=TO_NUMBER(:SOURCE_LINEAGE_NAME) AND "DELETED_AT"="L"."LINEAGE_ID")
filter("L"."LINEAGE_ID"<=TO_NUMBER(:SOURCE_STATE_ID))
12 - access("A"."OBJECTID"="$nso_col_1" AND "A"."SDE_STATE_ID"="$nso_col_2")
15 - access("A"."SDE_STATE_ID"<=TO_NUMBER(:SOURCE_STATE_ID))
16 - access("SL"."LINEAGE_NAME"=TO_NUMBER(:SOURCE_LINEAGE_NAME) AND
"A"."SDE_STATE_ID"="SL"."LINEAGE_ID")
filter("SL"."LINEAGE_ID"<=TO_NUMBER(:SOURCE_STATE_ID))
17 - filter("$nso_col_2"<=TO_NUMBER(:SOURCE_STATE_ID))
19 - access("SDE_STATE_ID">TO_NUMBER(:SYS_B_1))
filter("SDE_STATE_ID">TO_NUMBER(:SYS_B_1))
20 - access("L"."LINEAGE_NAME"=TO_NUMBER(:SOURCE_LINEAGE_NAME) AND "DELETED_AT"="L"."LINEAGE_ID")
filter("L"."LINEAGE_ID"<=TO_NUMBER(:SOURCE_STATE_ID))
47 rows selected.DB2 (staging)
SQL> explain plan for
2 SELECT V__101.*, SHAPE.fid,SHAPE.numofpts,SHAPE.entity,SHAPE.points,
SHAPE.rowid
FROM
3 4 5 (SELECT b.OBJECTID,b.CRT_DTE,b.CRT_SRC_CDE,b.CRT_AQUI_MTHD_CDE,b.CRT_USR_ID,
b.ADT_ACTN_CDE,b.ADT_ACTN_DTE,b.ADT_ACTN_SRC_CDE,b.ADT_ACTN_USR_ID,
6 7 b.TP_SITE_POINT_ID,b.SHAPE,b.SRC_ID,b.SRC_CRT_DTE,b.SRC_TYPE_CDE,
8 b.LCTN_STAT_CDE,b.FRZN_LCTN_IND,b.TP_NOTES FROM AMSOWNER.TP_SITE_POINT b
9 WHERE b.OBJECTID NOT IN (SELECT /*+ HASH_AJ */ SDE_DELETES_ROW_ID FROM
10 AMSOWNER.D101 WHERE DELETED_AT IN (SELECT l.lineage_id FROM
11 SDE.state_lineages l WHERE l.lineage_name = :source_lineage_name AND
12 l.lineage_id <= :source_state_id) AND SDE_STATE_ID = :"SYS_B_0") UNION ALL
13 SELECT a.OBJECTID,a.CRT_DTE,a.CRT_SRC_CDE,a.CRT_AQUI_MTHD_CDE,a.CRT_USR_ID,
14 a.ADT_ACTN_CDE,a.ADT_ACTN_DTE,a.ADT_ACTN_SRC_CDE,a.ADT_ACTN_USR_ID,
15 a.TP_SITE_POINT_ID,a.SHAPE,a.SRC_ID,a.SRC_CRT_DTE,a.SRC_TYPE_CDE,
16 a.LCTN_STAT_CDE,a.FRZN_LCTN_IND,a.TP_NOTES FROM AMSOWNER.A101 a,
17 SDE.state_lineages SL WHERE (a.OBJECTID, a.SDE_STATE_ID) NOT IN (SELECT /*+
HASH_AJ */ SDE_DELETES_ROW_ID,SDE_STATE_ID FROM AMSOWNER.D101 WHERE
18 19 DELETED_AT IN (SELECT l.lineage_id FROM SDE.state_lineages l WHERE
20 l.lineage_name = :source_lineage_name AND l.lineage_id <= :source_state_id)
21 AND SDE_STATE_ID > :"SYS_B_1") AND a.SDE_STATE_ID = SL.lineage_id AND
22 SL.lineage_name = :source_lineage_name AND SL.lineage_id <=
23 :source_state_id ) V__101 , AMSOWNER.F15 SHAPE where SHAPE.FID(+) =
24 V__101.SHAPE;
Explained.
SQL> @?/rdbms/admin/utlxplp.sql;
PLAN_TABLE_OUTPUT
Plan hash value: 4287458713
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 145 | 68150 | 401 (1)| 00:00:06 |
| 1 | NESTED LOOPS OUTER | | 145 | 68150 | 401 (1)| 00:00:06 |
| 2 | VIEW | | 145 | 47125 | 328 (1)| 00:00:05 |
| 3 | UNION-ALL | | | | | |
|* 4 | HASH JOIN ANTI | | 144 | 10224 | 324 (1)| 00:00:05 |
| 5 | TABLE ACCESS FULL | TP_SITE_POINT | 145 | 8410 | 322 (1)| 00:00:05 |
| 6 | VIEW | VW_NSO_1 | 1 | 13 | 2 (0)| 00:00:01 |
| 7 | NESTED LOOPS | | 1 | 50 | 2 (0)| 00:00:01 |
|* 8 | TABLE ACCESS BY INDEX ROWID| D101 | 1 | 39 | 1 (0)| 00:00:01 |
|* 9 | INDEX SKIP SCAN | D101_IDX1 | 1 | | 1 (0)| 00:00:01 |
|* 10 | INDEX UNIQUE SCAN | LINEAGES_PK | 1 | 11 | 1 (0)| 00:00:01 |
|* 11 | FILTER | | | | | |
| 12 | NESTED LOOPS | | 1 | 349 | 2 (0)| 00:00:01 |
| 13 | TABLE ACCESS BY INDEX ROWID | A101 | 1 | 338 | 1 (0)| 00:00:01 |
|* 14 | INDEX RANGE SCAN | A101_STATEID_IX1 | 1 | | 1 (0)| 00:00:01 |
|* 15 | INDEX UNIQUE SCAN | LINEAGES_PK | 1 | 11 | 1 (0)| 00:00:01 |
|* 16 | FILTER | | | | | |
| 17 | NESTED LOOPS | | 1 | 50 | 2 (0)| 00:00:01 |
|* 18 | TABLE ACCESS BY INDEX ROWID| D101 | 1 | 39 | 1 (0)| 00:00:01 |
|* 19 | INDEX RANGE SCAN | D101_IDX1 | 1 | | 1 (0)| 00:00:01 |
|* 20 | INDEX UNIQUE SCAN | LINEAGES_PK | 1 | 11 | 1 (0)| 00:00:01 |
| 21 | TABLE ACCESS BY INDEX ROWID | F15 | 1 | 145 | 1 (0)| 00:00:01 |
|* 22 | INDEX UNIQUE SCAN | F15_UK1 | 1 | | 1 (0)| 00:00:01 |
Predicate Information (identified by operation id):
4 - access("B"."OBJECTID"="$nso_col_1")
8 - filter("DELETED_AT"<=TO_NUMBER(:SOURCE_STATE_ID))
9 - access("SDE_STATE_ID"=TO_NUMBER(:SYS_B_0))
filter("SDE_STATE_ID"=TO_NUMBER(:SYS_B_0))
10 - access("L"."LINEAGE_NAME"=TO_NUMBER(:SOURCE_LINEAGE_NAME) AND
"DELETED_AT"="L"."LINEAGE_ID")
filter("L"."LINEAGE_ID"<=TO_NUMBER(:SOURCE_STATE_ID))
11 - filter( NOT EXISTS (SELECT /*+ HASH_AJ */ 0 FROM "AMSOWNER"."D101"
"D101","SDE"."STATE_LINEAGES" "L" WHERE :B1>TO_NUMBER(:SYS_B_1) AND
"DELETED_AT"="L"."LINEAGE_ID" AND "L"."LINEAGE_NAME"=TO_NUMBER(:SOURCE_LINEAGE_NAME) AND
"L"."LINEAGE_ID"<=TO_NUMBER(:SOURCE_STATE_ID) AND "SDE_STATE_ID"=:B2 AND
"SDE_DELETES_ROW_ID"=:B3 AND "DELETED_AT"<=TO_NUMBER(:SOURCE_STATE_ID) AND
"SDE_STATE_ID">TO_NUMBER(:SYS_B_1)))
14 - access("A"."SDE_STATE_ID"<=TO_NUMBER(:SOURCE_STATE_ID))
15 - access("SL"."LINEAGE_NAME"=TO_NUMBER(:SOURCE_LINEAGE_NAME) AND
"A"."SDE_STATE_ID"="SL"."LINEAGE_ID")
filter("SL"."LINEAGE_ID"<=TO_NUMBER(:SOURCE_STATE_ID))
16 - filter(:B1>TO_NUMBER(:SYS_B_1))
18 - filter("DELETED_AT"<=TO_NUMBER(:SOURCE_STATE_ID))
19 - access("SDE_DELETES_ROW_ID"=:B1 AND "SDE_STATE_ID"=:B2)
filter("SDE_STATE_ID">TO_NUMBER(:SYS_B_1))
20 - access("L"."LINEAGE_NAME"=TO_NUMBER(:SOURCE_LINEAGE_NAME) AND
"DELETED_AT"="L"."LINEAGE_ID")
filter("L"."LINEAGE_ID"<=TO_NUMBER(:SOURCE_STATE_ID))
22 - access("SHAPE"."FID"(+)="V__101"."SHAPE")
58 rows selected.rocr wrote:
oracle 10.2.0.2.0
solaris 10
same query, different databases (cloned from same source), different explain plans.
db parameters are identical.
DB1 (production)
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 113K| 49M| | 2926 (1)| 00:00:41 |DB2 (staging)
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 145 | 68150 | 401 (1)| 00:00:06 |
If you check the execution plans it's quite obvious that the two environments can not be identical. If you have the same (amount of) data, then one of the two estimates is way off. Which one is in the right ballpark, how many rows are returned by the query? The same applies to the remaining operation ids of the plan, which estimate is correct?
It's very likely that the underlying table/index statistics are not the same, and therefore you get different plans.
By the way, you're using bind variables, therefore the output of the EXPLAIN PLAN is only of limited use, since the actual plan at run time might be completely different due to bind variable peeking and potentially histograms created on some of the columns (which is the default in 10g due to the "FOR ALL COLUMNS SIZE AUTO" method_opt default parameter value).
If you haven't disabled the pre-configured statistics collection job that runs every night in 10g, you might get different statistics due to this job already.
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/ -
Hi,
I have a sql which is recently having a performance problems in Production. I have generated a explain plan for it trying to find out what it is doing but plan itself is close to 1000 lines. I want to check if there is any efficient way to go through big plan like this one and quickly find the damaging areas..
2) I also wanted to know if there is way to generate explain plans in HTML format which executed in past and have entry in dba_hist_sqltext.
3) I also have two sql_monitor reports which I want to compare. is there any efficient way to do it as well?
Please share your thoughts!
Thanks in advance!
Regards,
Suman-Hi,
I suggest you can try running sql advisor on the query maybe something fruitful comes up
http://www.oracle-base.com/articles/11g/sql-access-advisor-11gr1.php
I am not sure about the explain plan being printed in html format but
You may also want to try the sqlhistory.sql query from below page
http://evdbt.com/scripts/
I have used it many times to check on executions and explain plans which may have changed over the period
I have faced it many times , the query picks up a bad explain plan and performs poorly -
Quick way to look at explain plan for executing a package?
I can look at explain plans for queries without any problem. But i'm troubleshooting the performance of executing a package and i'm wondering if there is a way to look at what's happening without using EM tools? i.e. command lines.
for queries, i've used set autotrace on or explain plan for query...
but how do you do this for the execution of a package?Thanks for the reply..i've tried sql_trace=TRUE but somehow i don't get the execution plan..i only see the number of parses, executes and fetches...
e.g. in my tkprof output, i have:
one of the select statements is here
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.00 0.00 0 6 0 0
total 3 0.00 0.00 0 6 0 0
Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 58 (recursive depth: 1)
But there is no execution plan..i've never done this when executing a package...what am i missing? this works fine for query statements..but not for packages.. -
Explain plan shows 300T of TempSpc and 999 hours - tuning request
Hi,
I have a query which obtains summary statistics. There is an items table which contains the dictionary of items which can be recorded. There is an events table which contains the item ID, timestamp and a value. The query summarizes the data for each item. e.g. Mean, stddev, sample values, length. I have trimmed the query down as simply as possible and am having a problem with large temp space and runtime estimates in the explain plan. Here is the query:
WITH ChartItems AS (
SELECT
ci.itemid,
ci.label,
ci.category,
ci.description,
COUNT(*),
COUNT(distinct subject_id)
FROM mimic2v26.d_chartitems ci
JOIN mimic2v26.chartevents ce ON ce.itemid = ci.itemid
--WHERE ci.itemid = 51
GROUP BY ci.itemid,
ci.label,
ci.category,
ci.description
--select * from ChartItems;
, RawData AS (
SELECT DISTINCT
ci.itemid,
ci.label,
ci.category,
ci.description,
last_value(ce.value1) ignore nulls over (partition BY ci.itemid order by
ce.charttime ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS
value1_last
FROM ChartItems ci
JOIN mimic2v26.chartevents ce ON ce.itemid = ci.itemid
select * from RawData;Which gives this explain plan:
Plan hash value: 642453121
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 4811G| 1238T| | 3686M (13)|999:59:59 |
| 1 | VIEW | | 4811G| 1238T| | 3686M (13)|999:59:59 |
| 2 | HASH UNIQUE | | 4811G| 258T| | 3686M (13)|999:59:59 |
| 3 | WINDOW BUFFER | | 4811G| 258T| | 3686M (13)|999:59:59 |
| 4 | SORT GROUP BY | | 4811G| 258T| 317T| 3686M (13)|999:59:59 |
|* 5 | HASH JOIN | | 4811G| 258T| 4943M| 25M (90)| 85:14:28 |
| 6 | VIEW | VW_DAG_0 | 152M| 3199M| | 1366K (1)| 04:33:18 |
| 7 | HASH GROUP BY | | 152M| 4216M| 5839M| 1366K (1)| 04:33:18 |
|* 8 | HASH JOIN | | 152M| 4216M| | 147K (2)| 00:29:36 |
| 9 | TABLE ACCESS FULL | D_CHARTITEMS | 4832 | 96640 | | 7 (0)| 00:00:01 |
| 10 | INDEX FAST FULL SCAN| CHARTEVENTS_O2 | 196M| 1683M| | 147K (1)| 00:29:25 |
| 11 | TABLE ACCESS FULL | CHARTEVENTS | 196M| 6922M| | 616K (1)| 02:03:19 |
Predicate Information (identified by operation id):
5 - access("CE"."ITEMID"="ITEM_2")300T of temp space! Ouch.
TKPROF output (I let the query run for a short while. I let it run for ages earlier, but wasn't tracing the session. Should I let it run for longer?):
TKPROF: Release 11.2.0.3.0 - Development on Tue Jul 10 16:54:27 2012
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
Trace file: /oracle/11gr2/app/oracle/diag/rdbms/mimic2/mimic2/trace/mimic2_ora_6507.trc
Sort options: default
count = number of times OCI procedure was executed
cpu = cpu time in seconds executing
elapsed = elapsed time in seconds executing
disk = number of physical reads of buffers from disk
query = number of buffers gotten for consistent read
current = number of buffers gotten in current mode (usually for update)
rows = number of rows processed by the fetch or execute call
WITH ChartItems AS (
SELECT
ci.itemid,
ci.label,
ci.category,
ci.description,
COUNT(*),
COUNT(distinct subject_id)
FROM mimic2v26.d_chartitems ci
JOIN mimic2v26.chartevents ce ON ce.itemid = ci.itemid
GROUP BY ci.itemid,
ci.label,
ci.category,
ci.description
, RawData AS (
SELECT DISTINCT
ci.itemid,
ci.label,
ci.category,
ci.description,
last_value(ce.value1) ignore nulls over (partition BY ci.itemid order by
ce.charttime ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS
value1_last
FROM ChartItems ci
JOIN mimic2v26.chartevents ce ON ce.itemid = ci.itemid
select * from RawData
call count cpu elapsed disk query current rows
Parse 1 0.02 0.02 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 582.40 712.23 705238 737351 0 0
total 3 582.43 712.25 705238 737351 0 0
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 85
Number of plan statistics captured: 1
Rows (1st) Rows (avg) Rows (max) Row Source Operation
0 0 0 VIEW (cr=0 pr=0 pw=0 time=184 us cost=3686387254 size=1361581801333882 card=4811243114254)
0 0 0 HASH UNIQUE (cr=0 pr=0 pw=0 time=180 us cost=3686387254 size=283863343740986 card=4811243114254)
0 0 0 WINDOW BUFFER (cr=0 pr=0 pw=0 time=74 us cost=3686387254 size=283863343740986 card=4811243114254)
0 0 0 SORT GROUP BY (cr=0 pr=0 pw=0 time=59 us cost=3686387254 size=283863343740986 card=4811243114254)
178073889 178073889 178073889 HASH JOIN (cr=737351 pr=705238 pw=124635 time=476372451 us cost=25572251 size=283863343740986 card=4811243114254)
6211631 6211631 6211631 VIEW VW_DAG_0 (cr=613768 pr=581413 pw=35805 time=286546567 us cost=1366486 size=3354399576 card=152472708)
6211631 6211631 6211631 HASH GROUP BY (cr=613768 pr=581413 pw=35805 time=281271878 us cost=1366486 size=4421708532 card=152472708)
196182740 196182740 196182740 HASH JOIN (cr=613768 pr=545608 pw=0 time=557485047 us cost=147987 size=4421708532 card=152472708)
4832 4832 4832 TABLE ACCESS FULL D_CHARTITEMS (cr=18 pr=16 pw=0 time=13666 us cost=7 size=96640 card=4832)
196182740 196182740 196182740 INDEX FAST FULL SCAN CHARTEVENTS_O2 (cr=613750 pr=545592 pw=0 time=148428499 us cost=147046 size=1765644660 card=196182740)(object id 96501)
10683044 10683044 10683044 TABLE ACCESS FULL CHARTEVENTS (cr=123583 pr=123825 pw=0 time=25175510 us cost=616507 size=7258761380 card=196182740)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 1 0.00 0.00
db file sequential read 2 0.01 0.01
db file scattered read 3 0.02 0.03
direct path read 5265 0.75 77.13
asynch descriptor resize 1 0.00 0.00
direct path write temp 15077 0.71 45.54
direct path read temp 2387 0.29 13.54
SQL*Net break/reset to client 1 0.66 0.66
SQL*Net message from client 1 0.00 0.00
SQL ID: 7jby2dxrpkkm9 Plan Hash: 1388734953
select SYS_CONTEXT('USERENV','SESSIONID')
from
dual
call count cpu elapsed disk query current rows
Parse 1 0.00 0.01 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.00 0.00 0 0 0 1
total 3 0.00 0.01 0 0 0 1
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 85
Number of plan statistics captured: 1
Rows (1st) Rows (avg) Rows (max) Row Source Operation
1 1 1 FAST DUAL (cr=0 pr=0 pw=0 time=4 us cost=2 size=0 card=1)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 1 0.00 0.00
OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
call count cpu elapsed disk query current rows
Parse 2 0.02 0.04 0 0 0 0
Execute 2 0.00 0.00 0 0 0 0
Fetch 2 582.40 712.23 705238 737351 0 1
total 6 582.43 712.27 705238 737351 0 1
Misses in library cache during parse: 2
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 4 0.00 0.00
db file sequential read 2 0.01 0.01
db file scattered read 3 0.02 0.03
direct path read 5265 0.75 77.13
asynch descriptor resize 1 0.00 0.00
direct path write temp 15077 0.71 45.54
direct path read temp 2387 0.29 13.54
SQL*Net break/reset to client 1 0.66 0.66
SQL*Net message from client 3 14.99 15.01
OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
call count cpu elapsed disk query current rows
Parse 0 0.00 0.00 0 0 0 0
Execute 0 0.00 0.00 0 0 0 0
Fetch 0 0.00 0.00 0 0 0 0
total 0 0.00 0.00 0 0 0 0
Misses in library cache during parse: 0
2 user SQL statements in session.
0 internal SQL statements in session.
2 SQL statements in session.
Trace file: /oracle/11gr2/app/oracle/diag/rdbms/mimic2/mimic2/trace/mimic2_ora_6507.trc
Trace file compatibility: 11.1.0.7
Sort options: default
1 session in tracefile.
2 user SQL statements in trace file.
0 internal SQL statements in trace file.
2 SQL statements in trace file.
2 unique SQL statements in trace file.
24245 lines in trace file.
728 elapsed seconds in trace file.Optimizer parameters:
NAME TYPE VALUE
optimizer_capture_sql_plan_baselines boolean FALSE
optimizer_dynamic_sampling integer 2
optimizer_features_enable string 11.2.0.3
optimizer_index_caching integer 0
optimizer_index_cost_adj integer 100
optimizer_mode string ALL_ROWS
optimizer_secure_view_merging boolean TRUE
optimizer_use_invisible_indexes boolean FALSE
optimizer_use_pending_statistics boolean FALSE
optimizer_use_sql_plan_baselines boolean TRUE Can anyone help me figure out what's wrong?
This is a data warehouse, with up to date statistics. The DB is version 11.2.0.3.0
Thanks,
Danrp0428 wrote:
>
I trimmed the query down to the simplest that I could which still exhibited the problem
>
The DISTINCT isn't the issue. The issue is that the query you posted isn't necessary and doesn't appear to be represented in the plan that you posted.
That makes it hard to tell where the cardinality misestimates are coming from. How many records does the actual first query (the one with the group by) return? You have a SELECT * commented out - how many rows?No, it's not necessary, but then it isn't the full query. The estimates are still wrong when I pass the count columns through to the second query. The full query contains many more analytic functions in the second query, and some additions to the first. It could probably be cleaned up a little, but the current structure makes logical sense. Should I change the aggregates to analytics and move them into the second query? In any case, there definitely seems to be something wrong with the plan.
I don't know what you mean when you say "doesn't appear to be represented in the plan that you posted".
I just checked the first query and while the temp space has dropped to a reasonable amount, the number of rows in the hash join is still way off (I didn't notice before because I was looking at the temp space). The rows for d_chartitems and the index on chartevents are correct:
Plan hash value: 1249235674
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 152M| 35G| | 1366K (1)| 04:33:18 |
| 1 | VIEW | | 152M| 35G| | 1366K (1)| 04:33:18 |
| 2 | WINDOW SORT | | 152M| 4216M| 5839M| 1366K (1)| 04:33:18 |
|* 3 | HASH JOIN | | 152M| 4216M| | 147K (2)| 00:29:36 |
| 4 | TABLE ACCESS FULL | D_CHARTITEMS | 4832 | 96640 | | 7 (0)| 00:00:01 |
| 5 | INDEX FAST FULL SCAN| CHARTEVENTS_O2 | 196M| 1683M| | 147K (1)| 00:29:25 |
Predicate Information (identified by operation id):
3 - access("CE"."ITEMID"="CI"."ITEMID")Edited by: danscott on Jul 10, 2012 5:43 PM
Edited by: danscott on Jul 11, 2012 6:28 AM -
Help with interpreting explain plan (dbms_xplan) output
Hi all,
I'm trying to get to grips with reading and interpreting the explain plan or dbms_xplan output, and so I hope someone can help with the output below.
So, with the explain shown below, does it mean that...
a) it starts with step 8 and sends all rows to the nested loop in step 5
b) it only sends (or thinks it sends) 1 row to step 5 from step 8
c) For each row supplied from step 5, there will be an index lookup at step 8 to access the table at step 6
d) Step 8 only gets (or think it gets) 1 row
If it does mean that only 1 row is expected by the optimizer, and yet the full table scan should return 150,000 records, and the table has up to date statistiucs, what else would cause the cardinality to be so far off?
If it doesn't mean it will return 1 row then what does it mean ?
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | | | 945 (100)| |
| 1 | SORT GROUP BY | | 1 | 283 | 945 (3)| 00:00:05 |
|* 2 | FILTER | | | | | |
| 3 | NESTED LOOPS | | | | | |
| 4 | NESTED LOOPS | | 1 | 283 | 944 (3)| 00:00:05 |
| 5 | NESTED LOOPS | | 1 | 108 | 929 (3)| 00:00:05 |
|* 6 | MAT_VIEW ACCESS FULL | DEMOGRAPHICS_MV | 1 | 97 | 927 (3)| 00:00:05 |
|* 7 | MAT_VIEW ACCESS BY INDEX ROWID| NAMES_MV | 1 | 11 | 2 (0)| 00:00:01 |
|* 8 | INDEX RANGE SCAN | ORG_MV_IDX1 | 1 | | 1 (0)| 00:00:01 |
|* 9 | INDEX RANGE SCAN | PAY_IDX8 | 252 | | 4 (0)| 00:00:01 |
|* 10 | TABLE ACCESS BY INDEX ROWID | PAY_ALL | 1 | 175 | 15 (0)| 00:00:01 |
Predicate Information (identified by operation id):
8 - access("ORG_MV"."ORG_ID"="DEMO_MV"."ORG_ID")Many thanks for your help.Thank you Hemant and rp0428,
I read through that white paper which was really useful.
I ran query using GATHER_PLAN_STATISTICS and go tthe Estimate and Actual rows - wow - it is a long way out!!
| Id | Operation | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time | A-Rows | A-Time | Buffers | Reads | OMem | 1Mem | Used-Mem |
| 0 | SELECT STATEMENT | | 1 | | | 945 (100)| | 0 |00:18:11.39 | 2552K| 361K| | | |
| 1 | SORT GROUP BY | | 1 | 1 | 283 | 945 (3)| 00:00:05 | 0 |00:18:11.39 | 2552K| 361K| 1024 | 1024 | |
|* 2 | FILTER | | 1 | | | | | 0 |00:18:11.39 | 2552K| 361K| | | |
| 3 | NESTED LOOPS | | 1 | | | | | 0 |00:18:11.39 | 2552K| 361K| | | |
| 4 | NESTED LOOPS | | 1 | 1 | 283 | 944 (3)| 00:00:05 | 44M|00:04:59.03 | 598K| 63442 | | | |
| 5 | NESTED LOOPS | | 1 | 1 | 108 | 929 (3)| 00:00:05 | 109K|00:00:01.73 | 7807 | 7 | | | |
|* 6 | MAT_VIEW ACCESS FULL | DEMOGRAPHICS_MV | 1 | 1 | 97 | 927 (3)| 00:00:05 | 126K|00:00:00.26 | 5417 | 1 | | | |
|* 7 | MAT_VIEW ACCESS BY INDEX ROWID| NAMES_MV | 126K| 1 | 11 | 2 (0)| 00:00:01 | 109K|00:00:01.27 | 2390 | 6 | | | |
|* 8 | INDEX RANGE SCAN | ORG_MV_IDX1 | 126K| 1 | | 1 (0)| 00:00:01 | 126K|00:00:00.69 | 2023 | 6 | | | |
|* 9 | INDEX RANGE SCAN | PAY_IDX8 | 109K| 252 | | 4 (0)| 00:00:01 | 44M|00:04:03.07 | 590K| 63435 | | | |
|* 10 | TABLE ACCESS BY INDEX ROWID | PAY_ALL | 44M| 1 | 175 | 15 (0)| 00:00:01 | 0 |00:13:09.85 | 1954K| 297K| | | |
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------When I unravel the WHERE clause and remove the decode(nvl statements (which only evaluate the passed in parameters and provide default values where they are NULL) I get a much better plan and values
| Id | Operation | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time | A-Rows | A-Time | Buffers | Reads | OMem | 1Mem | Used-Mem |
| 0 | SELECT STATEMENT | | 1 | | | 157K(100)| | 0 |00:00:43.10 | 343K| 45190 | | | |
| 1 | SORT GROUP BY | | 1 | 1 | 283 | 157K (1)| 00:13:47 | 0 |00:00:43.10 | 343K| 45190 | 1024 | 1024 | |
| 2 | NESTED LOOPS | | 1 | | | | | 0 |00:00:43.10 | 343K| 45190 | | | |
| 3 | NESTED LOOPS | | 1 | 1 | 283 | 157K (1)| 00:13:47 | 0 |00:00:43.10 | 343K| 45190 | | | |
|* 4 | HASH JOIN | | 1 | 1 | 272 | 157K (1)| 00:13:47 | 0 |00:00:43.10 | 343K| 45190 | 720K| 720K| 171K (0)|
|* 5 | TABLE ACCESS BY INDEX ROWID | PAY_ALL | 1 | 2 | 350 | 156K (1)| 00:13:43 | 0 |00:00:43.10 | 343K| 45190 | | | |
|* 6 | INDEX RANGE SCAN | PAY_IDX7 | 1 | 3596K| | 15565 (1)| 00:01:22 | 7251K|00:00:50.88 | 45190 | 45190 | | | |
|* 7 | MAT_VIEW ACCESS FULL | DEMOGRAPHICS_MV | 0 | 126K| 11M| 919 (2)| 00:00:05 | 0 |00:00:00.01 | 0 | 0 | | | |
|* 8 | INDEX RANGE SCAN | ORG_MV_IDX1 | 0 | 1 | | 1 (0)| 00:00:01 | 0 |00:00:00.01 | 0 | 0 | | | |
|* 9 | MAT_VIEW ACCESS BY INDEX ROWID| NAMES_MV | 0 | 1 | 11 | 2 (0)| 00:00:01 | 0 |00:00:00.01 | 0 | 0 | | | |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Even though the result set is zero, the time to establish this came down from 35 minutes to 30 seconds and the plan has changed and is using a different index now!
Thanks for your help! -
What is the significance of "cost" column in explain plan
Hi,
Can anyone explain what is the meaning of the values which we get in the cost column in the explain plan..For Ex : Cost : 4500 . What does this value mean...and is it measured in which form of units...i mean seconds,nanoseconds etckingfisher,
Ok one more link for you but I shall quote the text also here,
http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/optimops.htm#i82005
The cost is an estimated value proportional to the expected resource use needed to execute the statement with a particular plan. The optimizer calculates the cost of access paths and join orders based on the estimated computer resources, which includes I/O, CPU, and memory.
And few paragraphs down,
13.4.1.3.3 Cost
The cost represents units of work or resource used. The query optimizer uses disk I/O, CPU usage, and memory usage as units of work. So, the cost used by the query optimizer represents an estimate of the number of disk I/Os and the amount of CPU and memory used in performing an operation. The operation can be scanning a table, accessing rows from a table by using an index, joining two tables together, or sorting a row set. The cost of a query plan is the number of work units that are expected to be incurred when the query is executed and its result produced.
The access path determines the number of units of work required to get data from a base table. The access path can be a table scan, a fast full index scan, or an index scan. During table scan or fast full index scan, multiple blocks are read from the disk in a single I/O operation. Therefore, the cost of a table scan or a fast full index scan depends on the number of blocks to be scanned and the multiblock read count value. The cost of an index scan depends on the levels in the B-tree, the number of index leaf blocks to be scanned, and the number of rows to be fetched using the rowid in the index keys. The cost of fetching rows using rowids depends on the index clustering factor. See "Assessing I/O for Blocks, not Rows".
The join cost represents the combination of the individual access costs of the two row sets being joined, plus the cost of the join operation.
Now I guess if you read this part, it should be pretty clear what cost is.Cost is an evlaution of the resource that is estimated by Oracle for every step incurred in the uery execution.There are no of steps and each may involve doing IO,consuming CPU and/or using memory.Cost is a factor which oracle uses combining all of these 3 (depending on the version) together to propose the work done or expected to be done in exeuting a query.So this actualy should represent the time spent exactly on each and every step.That's what the objective frm cost is.But at the moment,this is not there.There amy be a situation that cost is shown as very high but query is working fine.There are woraround which can bring the cost down for example using and tweaking optimizer_index_cost_adj parameter , we can propose oracle regarding our indexes and it may pick up lesser cost evaluation.What is mentioned is that this model is becoming more and more mature and in the next releases, we may see that cost is representing exactly the time that we would spend inthe query.At the moment,its not there.So as Chris mentioned,Tuning for low cost only is not a good way.
I suggest you grab a copy of JL's book.He has explained it much better in his book.
Hope I said some thing useful.
Aman.... -
Oracle not using its own explain plan
When I run a simple select query on an indexed column on a large (30 million records) table oracle creates a plan using the indexed column and at a cost of 4. However, what it actually does is do a table scan (I can see this in the 'Long Operations' tab in OEM).
The funny thing is that I have the same query in a ADO application and when the query is run from there, the same plan is created but no table scan is done - and the query returns in less than a second. However, with the table scan it is over a minute.
When run through SQL plus Oracle creates a plan including the table scan at a cost of 19030.
In another (dot net) application I used the: "Alter session set optimizer_index_caching=100" and "Alter session set optimizer_index_cost_adj=10" to try to force the optimizer to use the index. It creates the expected plan, but still does the table scan.
The query is in the form of:
"Select * from tab where indexedcol = something"
Im using Oracle 9i 9.2.0.1.0
Any ideas as I'm completely at a loss?Hello
It sounds to me like this has something to do with bind variable peeking which was introduced in 9i. If the predicate is
indexedcolumn = :bind_variablethe first time the query is parsed by oracle, it will "peek" at the value in the bind variable and see what it is and will generate an execution plan based on this. That same plan will be used for matching SQL.
If you use a litteral, it will generate the plan based on that, and will generate a separate plan for each litteral you use (depending on the value of the cursor_sharing initialisation parameter).
This can cause there to be a difference between the execution plan seen when issuing EXPLAIN PLAN FOR, and the actual exectuion plan used when the query is run.
Have a look at the following example:
tylerd@DEV2> CREATE TABLE dt_test_bvpeek(id number, col1 number)
2 /
Table created.
Elapsed: 00:00:00.14
tylerd@DEV2> INSERT
2 INTO
3 dt_test_bvpeek
4 SELECT
5 rownum,
6 CASE
7 WHEN MOD(rownum, 5) IN (0,1,2,3) THEN
8 1
9 ELSE
10 MOD(rownum, 5)
11 END
12 END
13 FROM
14 dual
15 CONNECT BY
16 LEVEL <= 100000
17 /
100000 rows created.
Elapsed: 00:00:00.81
tylerd@DEV2> select count(*), col1 from dt_test_bvpeek group by col1
2 /
COUNT(*) COL1
80000 1
20000 4
2 rows selected.
Elapsed: 00:00:00.09
tylerd@DEV2> CREATE INDEX dt_test_bvpeek_i1 ON dt_test_bvpeek(col1)
2 /
Index created.
Elapsed: 00:00:00.40
tylerd@DEV2> EXEC dbms_stats.gather_table_stats( ownname=>USER,-
tabname=>'DT_TEST_BVPEEK',-
method_opt=>'FOR ALL INDEXED COLUMNS SIZE 254',-
cascade=>TRUE -
);PL/SQL procedure successfully completed.
Elapsed: 00:00:00.73
tylerd@DEV2> EXPLAIN PLAN FOR
2 SELECT
3 *
4 FROM
5 dt_test_bvpeek
6 WHERE
7 col1 = 1
8 /
Explained.
Elapsed: 00:00:00.01
tylerd@DEV2> SELECT * FROM TABLE(DBMS_XPLAN.display)
2 /
PLAN_TABLE_OUTPUT
Plan hash value: 2611346395
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 78728 | 538K| 82 (52)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| DT_TEST_BVPEEK | 78728 | 538K| 82 (52)| 00:00:01 |
Predicate Information (identified by operation id):
1 - filter("COL1"=1)
13 rows selected.
Elapsed: 00:00:00.06The execution plan for col1=1 was chosen because oracle was able to see that based on the statistics, col1=1 would result in most of the rows from the table being returned.
tylerd@DEV2> EXPLAIN PLAN FOR
2 SELECT
3 *
4 FROM
5 dt_test_bvpeek
6 WHERE
7 col1 = 4
8 /
Explained.
Elapsed: 00:00:00.00
tylerd@DEV2> SELECT * FROM TABLE(DBMS_XPLAN.display)
2 /
PLAN_TABLE_OUTPUT
Plan hash value: 3223879139
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 21027 | 143K| 74 (21)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| DT_TEST_BVPEEK | 21027 | 143K| 74 (21)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | DT_TEST_BVPEEK_I1 | 21077 | | 29 (28)| 00:00:01 |
Predicate Information (identified by operation id):
2 - access("COL1"=4)
14 rows selected.
Elapsed: 00:00:00.04This time, the optimiser was able to see that col1=4 would result in far fewer rows so it chose to use an index. Look what happens however when we use a bind variable with EXPLAIN PLAN FOR - especially the number of rows the optimiser estimates to be returned from the table
tylerd@DEV2> var an_col1 NUMBER
tylerd@DEV2> exec :an_col1:=1;
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.00
tylerd@DEV2>
tylerd@DEV2> EXPLAIN PLAN FOR
2 SELECT
3 *
4 FROM
5 dt_test_bvpeek
6 WHERE
7 col1 = :an_col1
8 /
Explained.
Elapsed: 00:00:00.01
tylerd@DEV2> SELECT * FROM TABLE(DBMS_XPLAN.display)
2 /
PLAN_TABLE_OUTPUT
Plan hash value: 2611346395
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 49882 | 340K| 100 (60)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| DT_TEST_BVPEEK | 49882 | 340K| 100 (60)| 00:00:01 |
Predicate Information (identified by operation id):
1 - filter("COL1"=TO_NUMBER(:AN_COL1))
13 rows selected.
Elapsed: 00:00:00.04
tylerd@DEV2>
tylerd@DEV2> exec :an_col1:=4;
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.01
tylerd@DEV2>
tylerd@DEV2> EXPLAIN PLAN FOR
2 SELECT
3 *
4 FROM
5 dt_test_bvpeek
6 WHERE
7 col1 = :an_col1
8 /
Explained.
Elapsed: 00:00:00.01
tylerd@DEV2> SELECT * FROM TABLE(DBMS_XPLAN.display)
2 /
PLAN_TABLE_OUTPUT
Plan hash value: 2611346395
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 49882 | 340K| 100 (60)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| DT_TEST_BVPEEK | 49882 | 340K| 100 (60)| 00:00:01 |
Predicate Information (identified by operation id):
1 - filter("COL1"=TO_NUMBER(:AN_COL1))
13 rows selected.
Elapsed: 00:00:00.07For both values of the bind variable, the optimiser has no idea what the value will be so it has to make a calculation based on a formula which results in it estimating that the query will return roughly half of the rows in the table, and so it chooses a full scan.
Now when we actually run the query, the optimiser can take advantage of bind variable peeking and have a look at the value the first time round and base the execution plan on that:
tylerd@DEV2> exec :an_col1:=1;
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.00
tylerd@DEV2> SELECT
2 *
3 FROM
4 dt_test_bvpeek
5 WHERE
6 col1 = :an_col1
7 /
80000 rows selected.
Elapsed: 00:00:10.98
tylerd@DEV2> SELECT prev_sql_id FROM v$session WHERE audsid=SYS_CONTEXT('USERENV','SESSIONID')
2 /
PREV_SQL_ID
9t52uyyq67211
1 row selected.
Elapsed: 00:00:00.00
tylerd@DEV2> SELECT
2 operation,
3 options,
4 object_name
5 FROM
6 v$sql_plan
7 WHERE
8 sql_id = '9t52uyyq67211'
9 /
OPERATION OPTIONS OBJECT_NAME
SELECT STATEMENT
TABLE ACCESS FULL DT_TEST_BVPEEK
2 rows selected.
Elapsed: 00:00:00.03It saw that the bind variable value was 1 and that this would return most of the rows in the table so it chose a full scan.
tylerd@DEV2> exec :an_col1:=4
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.00
tylerd@DEV2> SELECT
2 *
3 FROM
4 dt_test_bvpeek
5 WHERE
6 col1 = :an_col1
7 /
20000 rows selected.
Elapsed: 00:00:03.50
tylerd@DEV2> SELECT prev_sql_id FROM v$session WHERE audsid=SYS_CONTEXT('USERENV','SESSIONID')
2 /
PREV_SQL_ID
9t52uyyq67211
1 row selected.
Elapsed: 00:00:00.00
tylerd@DEV2> SELECT
2 operation,
3 options,
4 object_name
5 FROM
6 v$sql_plan
7 WHERE
8 sql_id = '9t52uyyq67211'
9 /
OPERATION OPTIONS OBJECT_NAME
SELECT STATEMENT
TABLE ACCESS FULL DT_TEST_BVPEEK
2 rows selected.
Elapsed: 00:00:00.01Even though the value of the bind variable changed, the optimiser saw that it already had a cached version of the sql statement along with an execution plan, so it used that rather than regenerating the plan. We can check the reverse of this by causing the statement to be invalidated and re-parsed - there's lots of ways, but I'm just going to rename the table:
Elapsed: 00:00:00.03
tylerd@DEV2> alter table dt_test_bvpeek rename to dt_test_bvpeek1
2 /
Table altered.
Elapsed: 00:00:00.01
tylerd@DEV2>
20000 rows selected.
Elapsed: 00:00:04.81
tylerd@DEV2> SELECT prev_sql_id FROM v$session WHERE audsid=SYS_CONTEXT('USERENV','SESSIONID')
2 /
PREV_SQL_ID
6ztnn4fyt6y5h
1 row selected.
Elapsed: 00:00:00.00
tylerd@DEV2> SELECT
2 operation,
3 options,
4 object_name
5 FROM
6 v$sql_plan
7 WHERE
8 sql_id = '6ztnn4fyt6y5h'
9 /
OPERATION OPTIONS OBJECT_NAME
SELECT STATEMENT
TABLE ACCESS BY INDEX ROWID DT_TEST_BVPEEK1
INDEX RANGE SCAN DT_TEST_BVPEEK_I1
3 rows selected.
80000 rows selected.
Elapsed: 00:00:10.61
tylerd@DEV2> SELECT prev_sql_id FROM v$session WHERE audsid=SYS_CONTEXT('USERENV','SESSIONID')
2 /
PREV_SQL_ID
6ztnn4fyt6y5h
1 row selected.
Elapsed: 00:00:00.01
tylerd@DEV2> SELECT
2 operation,
3 options,
4 object_name
5 FROM
6 v$sql_plan
7 WHERE
8 sql_id = '6ztnn4fyt6y5h'
9 /
OPERATION OPTIONS OBJECT_NAME
SELECT STATEMENT
TABLE ACCESS BY INDEX ROWID DT_TEST_BVPEEK1
INDEX RANGE SCAN DT_TEST_BVPEEK_I1
3 rows selected.This time round, the optimiser peeked at the bind variable the first time the statement was exectued and found it to be 4, so it based the execution plan on that and chose an index range scan. When the statement was executed again, it used the plan it had already executed.
HTH
David -
Help in interpreting the output of explain plan
Hi,
I have written a query in two different ways and then run an explain plan on both of them. Both these queries give same result. I want to know which one will be more efficient. I am giving the output of explain plan for both the queries:
The second plan has a lower cost but has much higher consistent gets !!
Please advise.
Plan 1:
Execution Plan
0 SELECT STATEMENT Optimizer=HINT: FIRST_ROWS (Cost=8637 Card= 1 Bytes=10132)
1 0 SORT (ORDER BY) (Cost=8637 Card=1 Bytes=10132)
2 1 WINDOW (SORT) (Cost=8637 Card=1 Bytes=10132)
3 2 COUNT (STOPKEY)
4 3 VIEW (Cost=8635 Card=1 Bytes=10132)
5 4 SORT (ORDER BY) (Cost=8635 Card=1 Bytes=862)
6 5 WINDOW (SORT) (Cost=8635 Card=1 Bytes=862)
7 6 MAT_VIEW ACCESS (FULL) OF 'PRD_SEARCH_MVW' (MAT_VIEW) (Cost=8633 Card=1 Bytes=862)
Statistics
577 recursive calls
0 db block gets
39202 consistent gets
34798 physical reads
0 redo size
72348 bytes sent via SQL*Net to client
4295 bytes received via SQL*Net from client
9 SQL*Net roundtrips to/from client
10 sorts (memory)
0 sorts (disk)
100 rows processed
Plan-2
Execution Plan
0 SELECT STATEMENT Optimizer=HINT: FIRST_ROWS (Cost=982 Card=1 Bytes=10145)
1 0 SORT (ORDER BY) (Cost=982 Card=1 Bytes=10145)
2 1 WINDOW (SORT) (Cost=982 Card=1 Bytes=10145)
3 2 COUNT (STOPKEY)
4 3 VIEW (Cost=980 Card=1 Bytes=10145)
5 4 SORT (ORDER BY) (Cost=980 Card=1 Bytes=10132)
6 5 WINDOW (SORT) (Cost=980 Card=1 Bytes=10132)
7 6 WINDOW (SORT) (Cost=980 Card=1 Bytes=10132)
8 7 VIEW (Cost=977 Card=1 Bytes=10132)
9 8 WINDOW (SORT PUSHED RANK) (Cost=977 Card=1 Bytes=889)
10 9 NESTED LOOPS (Cost=976 Card=1 Bytes=889)
11 10 HASH JOIN (Cost=305 Card=670 Bytes=18090)
12 11 HASH JOIN (Cost=23 Card=140 Bytes=2240)
13 12 INDEX (FAST FULL SCAN) OF 'GLCAT_GRP_TO_CAT_PK' (INDEX (UNIQUE)) (Cost=2 Card=52 Bytes=364)
14 12 MAT_VIEW ACCESS (FULL) OF 'GLCAT_CAT_TO_MCAT' (MAT_VIEW) (Cost=20 Card=1039 Bytes=9351)
15 11 INDEX (FAST FULL SCAN) OF 'PCITEM2GLCATMCAT_FK_IDS' (INDEX) (Cost=281 Card=16903 Bytes=185933)
16 10 MAT_VIEW ACCESS (BY INDEX ROWID) OF 'PRD_SEARCH_MVW' (MAT_VIEW) (Cost=1 Card=1 Bytes=862)
17 16 INDEX (UNIQUE SCAN) OF 'PK_PRD_SEARCH_ID' (INDEX (UNIQUE)) (Cost=0 Card=1)
Statistics
481 recursive calls
2 db block gets
195742 consistent gets
7516 physical reads
0 redo size
71567 bytes sent via SQL*Net to client
6629 bytes received via SQL*Net from client
9 SQL*Net roundtrips to/from client
15 sorts (memory)
1 sorts (disk)
100 rows processedRegards
Madhup
Message was edited by:
MadhupThanks a lot for you input. I am posting both the queries below. My requirements are following:
1) I have a products table
2) I have Created grouping hierarchy - Groups, Categories and then Micro-categories - and have setup a separate table for each of them in my database
3) Then I have mapping tables, i.e. a table that stores group to category mapping, another table that stores category to micro-category mapping.
4) Products are mapped directly to micro-categories and one product could be mapped to multiple micro-categories.
5) I have created a materialized view on product and store the mappings as comma separated list of IDs - I have three fields there, on to store comma separated group id, second to store comma separated category ids and third to store the comma separated micro category ids to which the product is mapped.
Now I want to write a query that will return a specified number of matches from this table based on user defined criterion. There are few other filter cirterion apart from Group/Category and Microcategory. These are Company Name, Country, Type of company etc.
This query when run on production will be accessed very frequently - I expect the access to be in the tune of around 5-10 times per second.
There are 50 records in the group table
There are 500 categories
There are 20000 micro-categories
Group to category mapping table has around 1000 records
Category to microcategory table has around 25000 records
The product table has around 100,000 products.
Product to microcategory mapping table has 350000 records
The product mview has the same number of records as that in products table.
The first query uses the single materialized view to access data, however, it always does a full table scan and does not use any index.
When I noticed this in the explain plan, then I tried to write the second query which is using JOINs to arrive at the same output.
The explain plan now says that it is using Index scans.
I did a sample run of both the queries on my production system and I had to withdraw both of them as both brought my system to grinding halt within few minutes of going live.
My system at present receives around 3000 requests per hour during peak load and around 600 requests per hour during off-peak hours.
And I was testing these queries in Off-peak hours !!
Here are the two sql queries just for reference - there are several variables plugged in where clause which are the key drivers of the query:
SQL-1
SELECT DECODE(:OPT,2,A.SC,(MAX(A.SC) OVER (PARTITION BY A.PRD_SEARCH_COMPANY))) AS SO,
A.SC, A.PRD_SEARCH_ID,
A.PRD_SEARCH_COMPANY_ID, A.PRD_SEARCH_COMPANY, A.PRD_SEARCH_COMPANYID_ENCRYPTED,
A.PRD_SEARCH_PCID, A.PRD_SEARCH_URL, A.PRD_SEARCH_PC_CLNT_HOME,
A.PRD_SEARCH_CLNT_ENABLED, A.PRD_SEARCH_CODE, A.PRD_SEARCH_NAME,
A.PRD_SEARCH_DESC_SMALL, A.PRD_SEARCH_DESC_DETAILED, A.PRD_SEARCH_DESC_HTML,
A.PRD_SEARCH_IMG_SMALL, A.PRD_SEARCH_IMG_LARGE, A.PRD_SEARCH_WEIGHT_ITEM,
A.PRD_SEARCH_MODIFIEDDATE, A.PRD_SEARCH_SIZE, A.PRD_SEARCH_LABEL1,
A.PRD_SEARCH_LABEL1_VALUE, A.PRD_SEARCH_LABEL2, A.PRD_SEARCH_LABEL2_VALUE,
A.PRD_SEARCH_LABEL3, A.PRD_SEARCH_LABEL3_VALUE, A.PRD_SEARCH_LABEL4,
A.PRD_SEARCH_LABEL4_VALUE, A.PRD_SEARCH_LABEL5, A.PRD_SEARCH_LABEL5_VALUE,
A.PRD_SEARCH_LABEL6, A.PRD_SEARCH_LABEL6_VALUE, A.PRD_SEARCH_CAT_ID,
A.PRD_SEARCH_CAT_NAME, A.PRD_SEARCH_CAT_FLNAME, A.PRD_SEARCH_NAVIGATION_TREE,
A.PRD_SEARCH_NAVIGATION_TREE_ID,A.PRD_SEARCH_CITY, A.PRD_SEARCH_STATE,
A.PRD_SEARCH_COUNTRY, A.PRD_SEARCH_PRICE_SALE, A.PRD_SEARCH_PC_CLNT_TYPE,
A.PRD_SEARCH_PC_CLNT_TYPE_DESC,
A.PRD_SEARCH_COMPANY_PHONE, A.PRD_SEARCH_COMPANY_MOBILE, A.PRD_SEARCH_COMPANY_FAX,
A.PRD_SEARCH_COMPANY_EMAIL, A.PRD_SEARCH_GLCAT_MCAT_ID_LIST, A.PRD_SEARCH_GLCAT_CAT_ID_LIST,
A.PRD_SEARCH_GLCAT_GRP_ID_LIST, A.PRD_SEARCH_GL_COUNTRY_ISO, A.PRD_SEARCH_GLUSR_USR_ID,
A.PRD_SEARCH_TRUSTSEAL_CODE, A.PRD_SEARCH_CUSTTYPE_ID, A.PRD_SEARCH_CUSTTYPE_NAME,
A.PRD_SEARCH_CUSTTYPE_WEIGHT, A.PRD_SEARCH_CUSTTYPE_WEIGHT_TZ, A.PRD_SEARCH_CUSTTYPE_RANK,
A.PRD_SEARCH_PC_ITEM_HOTNEW, A.RK
FROM
(SELECT /*+ FIRST_ROWS (500) */ DECODE(:S_MODE,2,1,3,to_number(to_char(PRD_SEARCH_MODIFIEDDATE,'yyyymmdd')),1) AS SC,
PRD_SEARCH_ID,
PRD_SEARCH_COMPANY_ID, PRD_SEARCH_COMPANY, PRD_SEARCH_COMPANYID_ENCRYPTED,
PRD_SEARCH_PCID, PRD_SEARCH_URL, PRD_SEARCH_PC_CLNT_HOME,
PRD_SEARCH_CLNT_ENABLED, PRD_SEARCH_CODE, PRD_SEARCH_NAME,
PRD_SEARCH_DESC_SMALL, PRD_SEARCH_DESC_DETAILED, PRD_SEARCH_DESC_HTML,
PRD_SEARCH_IMG_SMALL, PRD_SEARCH_IMG_LARGE, PRD_SEARCH_WEIGHT_ITEM,
PRD_SEARCH_MODIFIEDDATE, PRD_SEARCH_SIZE, PRD_SEARCH_LABEL1,
PRD_SEARCH_LABEL1_VALUE, PRD_SEARCH_LABEL2, PRD_SEARCH_LABEL2_VALUE,
PRD_SEARCH_LABEL3, PRD_SEARCH_LABEL3_VALUE, PRD_SEARCH_LABEL4,
PRD_SEARCH_LABEL4_VALUE, PRD_SEARCH_LABEL5, PRD_SEARCH_LABEL5_VALUE,
PRD_SEARCH_LABEL6, PRD_SEARCH_LABEL6_VALUE, PRD_SEARCH_CAT_ID,
PRD_SEARCH_CAT_NAME, PRD_SEARCH_CAT_FLNAME, PRD_SEARCH_NAVIGATION_TREE,
PRD_SEARCH_NAVIGATION_TREE_ID,PRD_SEARCH_CITY, PRD_SEARCH_STATE,
PRD_SEARCH_COUNTRY, PRD_SEARCH_PRICE_SALE, PRD_SEARCH_PC_CLNT_TYPE,
PRD_SEARCH_PC_CLNT_TYPE_DESC,
PRD_SEARCH_COMPANY_PHONE, PRD_SEARCH_COMPANY_MOBILE, PRD_SEARCH_COMPANY_FAX,
PRD_SEARCH_COMPANY_EMAIL, PRD_SEARCH_GLCAT_MCAT_ID_LIST, PRD_SEARCH_GLCAT_CAT_ID_LIST,
PRD_SEARCH_GLCAT_GRP_ID_LIST, PRD_SEARCH_GL_COUNTRY_ISO, PRD_SEARCH_GLUSR_USR_ID,
PRD_SEARCH_TRUSTSEAL_CODE, PRD_SEARCH_CUSTTYPE_ID, PRD_SEARCH_CUSTTYPE_NAME,
PRD_SEARCH_CUSTTYPE_WEIGHT, PRD_SEARCH_CUSTTYPE_WEIGHT_TZ, PRD_SEARCH_CUSTTYPE_RANK,
PRD_SEARCH_PC_ITEM_HOTNEW,
ROW_NUMBER() OVER (PARTITION BY PRD_SEARCH_COMPANY_ID
ORDER BY DECODE(:S_MODE,2,1,3,to_number(to_char(PRD_SEARCH_MODIFIEDDATE,'yyyymmdd')),1) DESC) AS RK
FROM PRD_SEARCH
WHERE DECODE(:GRP_ID_STR,NULL,1,REGEXP_INSTR(','||REPLACE(PRD_SEARCH_GLCAT_GRP_ID_LIST,' ','')||',',:MYGRP_ID_STR)) > 0
AND DECODE(:CAT_ID_STR,NULL,1,REGEXP_INSTR(','||REPLACE(PRD_SEARCH_GLCAT_CAT_ID_LIST,' ','')||',',:MYCAT_ID_STR)) > 0
AND DECODE(:MCAT_ID_STR,NULL,1,REGEXP_INSTR(','||REPLACE(PRD_SEARCH_GLCAT_MCAT_ID_LIST,' ','')||',',:MYMCAT_ID_STR)) > 0
AND DECODE(:ITEM_ID_STR,NULL,1,REGEXP_INSTR(','||PRD_SEARCH_ID||',',:MYITEM_ID_STR)) > 0
AND DECODE(:COUNTRY_ISO,NULL,1,REGEXP_INSTR(','||PRD_SEARCH_GL_COUNTRY_ISO||',',:COUNTRY_ISO)) > 0
AND DECODE(nvl(NULL,0),0,1,PRD_SEARCH_COMPANY_ID) = DECODE(nvl(NULL,0),0,1,NULL)
AND DECODE(nvl(NULL,0),0,1,PRD_SEARCH_GLUSR_USR_ID) = DECODE(nvl(NULL,0),0,1,NULL)
AND PRD_SEARCH_CLNT_ENABLED >= nvl(:LIST_TYPE,0)
AND NVL(Length(PRD_SEARCH_TRUSTSEAL_CODE),0) >= :TSONLY
ORDER BY SC DESC, PRD_SEARCH_CUSTTYPE_WEIGHT ASC, DBMS_RANDOM.RANDOM
) A
WHERE A.RK <= :MY_PRD_PER_COMP
AND ROWNUM <= :MYMAXREC
ORDER BY SO DESC, DECODE(:OPT,2,'1',A.PRD_SEARCH_COMPANY), A.RK ASC, DBMS_RANDOM.RANDOM
SQL-2
SELECT
DECODE(:OPT,2,SC,(MAX(SC) OVER (PARTITION BY PRD_SEARCH_COMPANY))) AS SO,
SC, PRD_SEARCH_ID,
PRD_SEARCH_COMPANY_ID, PRD_SEARCH_COMPANY, PRD_SEARCH_COMPANYID_ENCRYPTED,
PRD_SEARCH_PCID, PRD_SEARCH_URL, PRD_SEARCH_PC_CLNT_HOME,
PRD_SEARCH_CLNT_ENABLED, PRD_SEARCH_CODE, PRD_SEARCH_NAME,
PRD_SEARCH_DESC_SMALL, PRD_SEARCH_DESC_DETAILED, PRD_SEARCH_DESC_HTML,
PRD_SEARCH_IMG_SMALL, PRD_SEARCH_IMG_LARGE, PRD_SEARCH_WEIGHT_ITEM,
PRD_SEARCH_MODIFIEDDATE, PRD_SEARCH_SIZE, PRD_SEARCH_LABEL1,
PRD_SEARCH_LABEL1_VALUE, PRD_SEARCH_LABEL2, PRD_SEARCH_LABEL2_VALUE,
PRD_SEARCH_LABEL3, PRD_SEARCH_LABEL3_VALUE, PRD_SEARCH_LABEL4,
PRD_SEARCH_LABEL4_VALUE, PRD_SEARCH_LABEL5, PRD_SEARCH_LABEL5_VALUE,
PRD_SEARCH_LABEL6, PRD_SEARCH_LABEL6_VALUE, PRD_SEARCH_CAT_ID,
PRD_SEARCH_CAT_NAME, PRD_SEARCH_CAT_FLNAME, PRD_SEARCH_NAVIGATION_TREE,
PRD_SEARCH_NAVIGATION_TREE_ID,PRD_SEARCH_CITY, PRD_SEARCH_STATE,
PRD_SEARCH_COUNTRY, PRD_SEARCH_PRICE_SALE, PRD_SEARCH_PC_CLNT_TYPE,
PRD_SEARCH_PC_CLNT_TYPE_DESC,
PRD_SEARCH_COMPANY_PHONE, PRD_SEARCH_COMPANY_MOBILE, PRD_SEARCH_COMPANY_FAX,
PRD_SEARCH_COMPANY_EMAIL, PRD_SEARCH_GLCAT_MCAT_ID_LIST, PRD_SEARCH_GLCAT_CAT_ID_LIST,
PRD_SEARCH_GLCAT_GRP_ID_LIST, PRD_SEARCH_GL_COUNTRY_ISO, PRD_SEARCH_GLUSR_USR_ID,
PRD_SEARCH_TRUSTSEAL_CODE, PRD_SEARCH_CUSTTYPE_ID, PRD_SEARCH_CUSTTYPE_NAME,
PRD_SEARCH_CUSTTYPE_WEIGHT, PRD_SEARCH_CUSTTYPE_WEIGHT_TZ, PRD_SEARCH_CUSTTYPE_RANK,
PRD_SEARCH_PC_ITEM_HOTNEW, RK
FROM
SELECT
/*+ FIRST_ROWS (500) */ DECODE(:OPT,2,SC,(MAX(SC) OVER (PARTITION BY PRD_SEARCH_COMPANY))) AS SO,
SC,PRD_SEARCH_ID,
PRD_SEARCH_COMPANY_ID, PRD_SEARCH_COMPANY, PRD_SEARCH_COMPANYID_ENCRYPTED,
PRD_SEARCH_PCID, PRD_SEARCH_URL, PRD_SEARCH_PC_CLNT_HOME,
PRD_SEARCH_CLNT_ENABLED, PRD_SEARCH_CODE, PRD_SEARCH_NAME,
PRD_SEARCH_DESC_SMALL, PRD_SEARCH_DESC_DETAILED, PRD_SEARCH_DESC_HTML,
PRD_SEARCH_IMG_SMALL, PRD_SEARCH_IMG_LARGE, PRD_SEARCH_WEIGHT_ITEM,
PRD_SEARCH_MODIFIEDDATE, PRD_SEARCH_SIZE, PRD_SEARCH_LABEL1,
PRD_SEARCH_LABEL1_VALUE, PRD_SEARCH_LABEL2, PRD_SEARCH_LABEL2_VALUE,
PRD_SEARCH_LABEL3, PRD_SEARCH_LABEL3_VALUE, PRD_SEARCH_LABEL4,
PRD_SEARCH_LABEL4_VALUE, PRD_SEARCH_LABEL5, PRD_SEARCH_LABEL5_VALUE,
PRD_SEARCH_LABEL6, PRD_SEARCH_LABEL6_VALUE, PRD_SEARCH_CAT_ID,
PRD_SEARCH_CAT_NAME, PRD_SEARCH_CAT_FLNAME, PRD_SEARCH_NAVIGATION_TREE,
PRD_SEARCH_NAVIGATION_TREE_ID,PRD_SEARCH_CITY, PRD_SEARCH_STATE,
PRD_SEARCH_COUNTRY, PRD_SEARCH_PRICE_SALE, PRD_SEARCH_PC_CLNT_TYPE,
PRD_SEARCH_PC_CLNT_TYPE_DESC,
PRD_SEARCH_COMPANY_PHONE, PRD_SEARCH_COMPANY_MOBILE, PRD_SEARCH_COMPANY_FAX,
PRD_SEARCH_COMPANY_EMAIL, PRD_SEARCH_GLCAT_MCAT_ID_LIST, PRD_SEARCH_GLCAT_CAT_ID_LIST,
PRD_SEARCH_GLCAT_GRP_ID_LIST, PRD_SEARCH_GL_COUNTRY_ISO, PRD_SEARCH_GLUSR_USR_ID,
PRD_SEARCH_TRUSTSEAL_CODE, PRD_SEARCH_CUSTTYPE_ID, PRD_SEARCH_CUSTTYPE_NAME,
PRD_SEARCH_CUSTTYPE_WEIGHT, PRD_SEARCH_CUSTTYPE_WEIGHT_TZ, PRD_SEARCH_CUSTTYPE_RANK,
PRD_SEARCH_PC_ITEM_HOTNEW,
ROW_NUMBER() OVER (PARTITION BY PRD_SEARCH_COMPANY_ID
ORDER BY DECODE(:S_MODE,2,1,3,TO_NUMBER(TO_CHAR(PRD_SEARCH_MODIFIEDDATE,'YYYYMMDD')),1) DESC) AS RK
FROM
SELECT
DECODE(:S_MODE,2,1,3,TO_NUMBER(TO_CHAR(PRD_SEARCH_MODIFIEDDATE,'YYYYMMDD')),1) AS SC,
PRD_SEARCH_ID,
PRD_SEARCH_COMPANY_ID, PRD_SEARCH_COMPANY, PRD_SEARCH_COMPANYID_ENCRYPTED,
PRD_SEARCH_PCID, PRD_SEARCH_URL, PRD_SEARCH_PC_CLNT_HOME,
PRD_SEARCH_CLNT_ENABLED, PRD_SEARCH_CODE, PRD_SEARCH_NAME,
PRD_SEARCH_DESC_SMALL, PRD_SEARCH_DESC_DETAILED, PRD_SEARCH_DESC_HTML,
PRD_SEARCH_IMG_SMALL, PRD_SEARCH_IMG_LARGE, PRD_SEARCH_WEIGHT_ITEM,
PRD_SEARCH_MODIFIEDDATE, PRD_SEARCH_SIZE, PRD_SEARCH_LABEL1,
PRD_SEARCH_LABEL1_VALUE, PRD_SEARCH_LABEL2, PRD_SEARCH_LABEL2_VALUE,
PRD_SEARCH_LABEL3, PRD_SEARCH_LABEL3_VALUE, PRD_SEARCH_LABEL4,
PRD_SEARCH_LABEL4_VALUE, PRD_SEARCH_LABEL5, PRD_SEARCH_LABEL5_VALUE,
PRD_SEARCH_LABEL6, PRD_SEARCH_LABEL6_VALUE, PRD_SEARCH_CAT_ID,
PRD_SEARCH_CAT_NAME, PRD_SEARCH_CAT_FLNAME, PRD_SEARCH_NAVIGATION_TREE,
PRD_SEARCH_NAVIGATION_TREE_ID,PRD_SEARCH_CITY, PRD_SEARCH_STATE,
PRD_SEARCH_COUNTRY, PRD_SEARCH_PRICE_SALE, PRD_SEARCH_PC_CLNT_TYPE,
PRD_SEARCH_PC_CLNT_TYPE_DESC,
PRD_SEARCH_COMPANY_PHONE, PRD_SEARCH_COMPANY_MOBILE, PRD_SEARCH_COMPANY_FAX,
PRD_SEARCH_COMPANY_EMAIL, PRD_SEARCH_GLCAT_MCAT_ID_LIST, PRD_SEARCH_GLCAT_CAT_ID_LIST,
PRD_SEARCH_GLCAT_GRP_ID_LIST, PRD_SEARCH_GL_COUNTRY_ISO, PRD_SEARCH_GLUSR_USR_ID,
PRD_SEARCH_TRUSTSEAL_CODE, PRD_SEARCH_CUSTTYPE_ID, PRD_SEARCH_CUSTTYPE_NAME,
PRD_SEARCH_CUSTTYPE_WEIGHT, PRD_SEARCH_CUSTTYPE_WEIGHT_TZ, PRD_SEARCH_CUSTTYPE_RANK,
PRD_SEARCH_PC_ITEM_HOTNEW,
ROW_NUMBER() OVER (PARTITION BY P.PRD_SEARCH_ID ORDER BY P.PRD_SEARCH_ID) RK1
FROM
GLCAT_GRP_TO_CAT G2C, GLCAT_CAT_TO_MCAT C2M, PC_ITEM_TO_GLCAT_MCAT M, PRD_SEARCH P
WHERE
G2C.FK_GLCAT_CAT_ID = C2M.FK_GLCAT_CAT_ID
AND C2M.FK_GLCAT_MCAT_ID = M.FK_GLCAT_MCAT_ID
AND M.FK_PC_ITEM_ID = P.PRD_SEARCH_ID
AND DECODE(:MCAT_ID_STR, NULL, 1, INSTR(','||:MCAT_ID_STR||',',','||M.FK_GLCAT_MCAT_ID||',',1))> 0
AND DECODE(:CAT_ID_STR, NULL, 1, INSTR(','||:CAT_ID_STR||',',','||C2M.FK_GLCAT_CAT_ID||',',1)) > 0
AND DECODE(:GRP_ID_STR, NULL, 1, INSTR(','||:GRP_ID_STR||',',','||G2C.FK_GLCAT_GRP_ID||',',1)) > 0
AND DECODE(:ITEM_ID_STR,NULL,1,INSTR(','||:ITEM_ID_STR||',' , ','||P.PRD_SEARCH_ID||',')) > 0
AND DECODE(:COUNTRY_ISO,NULL,1,INSTR(','||:COUNTRY_ISO||',', ','||P.PRD_SEARCH_GL_COUNTRY_ISO||',')) > 0
AND DECODE(NVL(:COMPANY_ID,0),0,1,P.PRD_SEARCH_COMPANY_ID) = DECODE(NVL(:COMPANY_ID,0),0,1,:COMPANY_ID)
AND DECODE(NVL(:GLUSR_ID,0),0,1,P.PRD_SEARCH_GLUSR_USR_ID) = DECODE(NVL(:GLUSR_ID,0),0,1,:GLUSR_ID)
AND P.PRD_SEARCH_CLNT_ENABLED >= NVL(:LIST_TYPE,0)
AND NVL(LENGTH(P.PRD_SEARCH_TRUSTSEAL_CODE),0) >= :TSONLY
WHERE RK1=1
ORDER BY SC DESC, PRD_SEARCH_CUSTTYPE_WEIGHT ASC, DBMS_RANDOM.RANDOM
) A
WHERE A.RK <= :MY_PRD_PER_COMP
AND ROWNUM <= :MYMAXREC
ORDER BY A.SO DESC, DECODE(:OPT,2,'1', A.PRD_SEARCH_COMPANY), A.RK ASC, DBMS_RANDOM.RANDOMRegards
Madhup -
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 only in spool file
Hi there,
I am trying to spool only my explain plan to a file, at the moment i can only return all the results and then explain plan to the file. This is a bit of a problem as i am running some rather long queries and some of them return over 80MB of data. this is what i have so far:
set termout off
timing start
set autotrace on
set heading off
spool h:\test1.lst
select unique1 from table1;
timing stop
spool off
set autotrace off
set termout on
any help on this would be great.
Thanks!Or for a handy way to preview the expected plan without executing the query, try www.williamrobertson.net/code/xplan.sql
SQL> SELECT COUNT(*) FROM dept d
2 WHERE EXISTS
3 ( SELECT NULL FROM emp e
4 WHERE e.deptno = d.deptno )
5
SQL> -- Note we did not execute anything...
SQL> @xplan
Plan hash value: 4196393176
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 6 | 4 (25)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 6 | | |
| 2 | NESTED LOOPS | | 3 | 18 | 4 (25)| 00:00:01 |
| 3 | SORT UNIQUE | | 14 | 42 | 3 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL| EMP | 14 | 42 | 3 (0)| 00:00:01 |
|* 5 | INDEX UNIQUE SCAN | PK_DEPT | 1 | 3 | 0 (0)| 00:00:01 |
Predicate Information (identified by operation id):
5 - access("E"."DEPTNO"="D"."DEPTNO")
SQL> -- And the query is still there:
SQL> l
1 SELECT COUNT(*) FROM dept d
2 WHERE EXISTS
3 ( SELECT NULL FROM emp e
4* WHERE e.deptno = d.deptno ) -
Explain plan left the building
Hello guys, i have interesting problem, at least it seemed to me like that.
I am on 10.2.0.4.0 and for every statement i do explain plan i get the same plan ???.
Propably very known issue to some, but i didn't exeperienced that till now, so if somene have some advice, please share.
E.g.
SQL> explain plan for select user from dual;
Explained.
SQL> select * from table(dbms_xplan.display);
Plan hash value: 3995103059
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Inst |
| 0 | SELECT STATEMENT REMOTE | | 1 | 96 | 97591 (5)| 00:05:07 | |
| 1 | SORT ORDER BY | | 1 | 96 | 97591 (5)| 00:05:07 | |
|* 2 | TABLE ACCESS BY INDEX ROWID| CCONTACT_ALL | 1 | 54 | 3 (0)| 00:00:01 | VIPBS~ |
| 3 | NESTED LOOPS | | 1 | 96 | 97590 (5)| 00:05:07 | |
|* 4 | TABLE ACCESS FULL | CUSTOMER_ALL | 1 | 42 | 97587 (5)| 00:05:07 | VIPBS~ |
|* 5 | INDEX RANGE SCAN | PKCCONTACT_ALL | 1 | | 2 (0)| 00:00:01 | VIPBS~ |
Predicate Information (identified by operation id):
2 - filter("A1"."CCCONTRACT"='X')
4 - filter((TO_NUMBER("A2"."CSCOMPTAXNO")=3007943362918 OR
TO_NUMBER("A2"."PASSPORTNO")=0109965330447) AND (TO_NUMBER("A2"."CSLEVEL")=10 OR
TO_NUMBER("A2"."CSLEVEL")=20 AND "A2"."TMCODE"<>59 AND "A2"."TMCODE"<>42 AND "A2"."TMCODE"<>61
AND "A2"."TMCODE"<>11 AND "A2"."TMCODE"<>19) AND "A2"."CSTYPE"='a' AND "A2"."PAYMNTRESP"='X')
5 - access("A1"."CUSTOMER_ID"="A2"."CUSTOMER_ID")
filter("A1"."CUSTOMER_ID"<>0)
Note
- 'PLAN_TABLE' is old version
- fully remote statement
28 rows selected....so, it looks like i am doing all that just with select user from dual .... : ) ... ok
SQL> explain plan for
2 SELECT param_value
3 FROM ncis.cis_case_script_vars
4 WHERE case_id = 296645706 AND seq = 1 AND param_name = 'OHOPNAMT';
Explained.
SQL> select * from table(dbms_xplan.display);
Plan hash value: 3995103059
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Inst |
| 0 | SELECT STATEMENT REMOTE | | 1 | 96 | 97591 (5)| 00:05:07 | |
| 1 | SORT ORDER BY | | 1 | 96 | 97591 (5)| 00:05:07 | |
|* 2 | TABLE ACCESS BY INDEX ROWID| CCONTACT_ALL | 1 | 54 | 3 (0)| 00:00:01 | VIPBS~ |
| 3 | NESTED LOOPS | | 1 | 96 | 97590 (5)| 00:05:07 | |
|* 4 | TABLE ACCESS FULL | CUSTOMER_ALL | 1 | 42 | 97587 (5)| 00:05:07 | VIPBS~ |
|* 5 | INDEX RANGE SCAN | PKCCONTACT_ALL | 1 | | 2 (0)| 00:00:01 | VIPBS~ |
Predicate Information (identified by operation id):
2 - filter("A1"."CCCONTRACT"='X')
4 - filter((TO_NUMBER("A2"."CSCOMPTAXNO")=3007943362918 OR
TO_NUMBER("A2"."PASSPORTNO")=0109965330447) AND (TO_NUMBER("A2"."CSLEVEL")=10 OR
TO_NUMBER("A2"."CSLEVEL")=20 AND "A2"."TMCODE"<>59 AND "A2"."TMCODE"<>42 AND "A2"."TMCODE"<>61
AND "A2"."TMCODE"<>11 AND "A2"."TMCODE"<>19) AND "A2"."CSTYPE"='a' AND "A2"."PAYMNTRESP"='X')
5 - access("A1"."CUSTOMER_ID"="A2"."CUSTOMER_ID")
filter("A1"."CUSTOMER_ID"<>0)
Note
- 'PLAN_TABLE' is old version
- fully remote statement
28 rows selected.
SQL>..same plan for different sql...
..and now, i am trying to explain plan for several easy sqls but look...
SQL> explain plan for select * from all_objects where rownum < 2;
explain plan for select * from all_objects where rownum < 2
ERROR at line 1:
ORA-01039: insufficient privileges on underlying objects of the view
SQL> explain plan for select * from user_tables ;
explain plan for select * from user_tables
ERROR at line 1:
ORA-01039: insufficient privileges on underlying objects of the view
SQL> desc all_objects
Name Null? Type
OWNER NOT NULL VARCHAR2(30)
OBJECT_NAME NOT NULL VARCHAR2(30)
SUBOBJECT_NAME VARCHAR2(30)
OBJECT_ID NOT NULL NUMBER
DATA_OBJECT_ID NUMBER
OBJECT_TYPE VARCHAR2(19)
CREATED NOT NULL DATE
LAST_DDL_TIME NOT NULL DATE
TIMESTAMP VARCHAR2(19)
STATUS VARCHAR2(7)
TEMPORARY VARCHAR2(1)
GENERATED VARCHAR2(1)
SECONDARY VARCHAR2(1)...i can't figure this out... maybe i have to flush 'explain plan' ? it's ok if it sounds funny,im off with ideas..
then i tried to explain this sql:
SQL> explain plan for
2 SELECT param_value
3 FROM ncis.cis_case_script_vars
4 WHERE case_id = 296645706 AND seq = 1 AND param_name = 'OHOPNAMT';
Explained.
SQL> select * from table(dbms_xplan.display);
Plan hash value: 3995103059
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Inst |
| 0 | SELECT STATEMENT REMOTE | | 1 | 96 | 97591 (5)| 00:05:07 | |
| 1 | SORT ORDER BY | | 1 | 96 | 97591 (5)| 00:05:07 | |
|* 2 | TABLE ACCESS BY INDEX ROWID| CCONTACT_ALL | 1 | 54 | 3 (0)| 00:00:01 | VIPBS~ |
| 3 | NESTED LOOPS | | 1 | 96 | 97590 (5)| 00:05:07 | |
|* 4 | TABLE ACCESS FULL | CUSTOMER_ALL | 1 | 42 | 97587 (5)| 00:05:07 | VIPBS~ |
|* 5 | INDEX RANGE SCAN | PKCCONTACT_ALL | 1 | | 2 (0)| 00:00:01 | VIPBS~ |
Predicate Information (identified by operation id):
2 - filter("A1"."CCCONTRACT"='X')
4 - filter((TO_NUMBER("A2"."CSCOMPTAXNO")=3007943362918 OR
TO_NUMBER("A2"."PASSPORTNO")=0109965330447) AND (TO_NUMBER("A2"."CSLEVEL")=10 OR
TO_NUMBER("A2"."CSLEVEL")=20 AND "A2"."TMCODE"<>59 AND "A2"."TMCODE"<>42 AND "A2"."TMCODE"<>61
AND "A2"."TMCODE"<>11 AND "A2"."TMCODE"<>19) AND "A2"."CSTYPE"='a' AND "A2"."PAYMNTRESP"='X')
5 - access("A1"."CUSTOMER_ID"="A2"."CUSTOMER_ID")
filter("A1"."CUSTOMER_ID"<>0)
Note
- 'PLAN_TABLE' is old version
- fully remote statement
28 rows selected.
SQL>..and got the same plan again....
anyone with suggestons, anyone encountered this behaviour ?Vili Dialis wrote:
Is there some way to force usage of one of them explicitly, how can i know which one is currently used ?
So what happend here ?
I am using what plan table of the above, and why that table generates always the same plan ?
*/To bypass the problem (probably), and to see how it happened (possibly) see http://jonathanlewis.wordpress.com/2010/01/25/old-plan_table/
Not sure why you keep getting the same plan, but dbms_xplan does a 'select where plan_id = (select max(plan_id) ..) so perhaps the plan_table(s) you keep using have an artificially high plan_id which is always getting selected. (You could try doing: delete from plan_table ; commit; )
Regards
Jonathan Lewis
http://jonathanlewis.wordpress.com
http://www.jlcomp.demon.co.uk
A general reminder about "Forum Etiquette / Reward Points": http://forums.oracle.com/forums/ann.jspa?annID=718
If you never mark your questions as answered people will eventually decide that it's not worth trying to answer you because they will never know whether or not their answer has been of any use, or whether you even bothered to read it.
It is also important to mark answers that you thought helpful - again it lets other people know that you appreciate their help, but it also acts as a pointer for other people when they are researching the same question, moreover it means that when you mark a bad or wrong answer as helpful someone may be prompted to tell you (and the rest of the forum) what's so bad or wrong about the answer you found helpful. -
Weird explain plan on multi-level structured XmlType column
Hello,
am running an explain on the follwing query on 11.2.0.2:
SELECT
T1.EVENT_ID,
ACTION_SUB_ID,
PARAM_KEY,
PARAM_VALUE,
TO_DATE('2013-12-10', 'YYYY-MM-DD')
FROM T_C_RMP_MNTRNG_XML_FULL_IL ,
XMLTABLE('/monitoring' PASSING XML_CONTENT COLUMNS
EVENT_ID VARCHAR2(4000) PATH 'eventId',
ACTIONS XMLTYPE PATH 'action'
) T1,
XMLTABLE('/action' PASSING T1.ACTIONS COLUMNS
ACTION_SUB_ID NUMBER(10,0) PATH 'actionSubId',
PARAMS xmltype PATH 'param'
) T2,
XMLTABLE('/param' PASSING T2.params columns
PARAM_KEY VARCHAR2(4000) PATH 'key',
PARAM_VALUE VARCHAR2(1000) PATH 'value'
) T3
WHERE MESSAGE_ID = 4972102 ;
Although MESSAGE_ID is the primary key of T_C_RMP_MNTRNG_XML_FULL_IL and thus there is only one record matching the condition, I get an explain plan with huge costs, 500MB of data and an estimated 10 hour runtime:
PLAN_TABLE_OUTPUT
Plan hash value: 4011854835
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 223K| 489M| 3111K (1)| 10:22:17 |
| 1 | NESTED LOOPS | | | | | |
| 2 | NESTED LOOPS | | 223K| 489M| 3111K (1)| 10:22:17 |
| 3 | NESTED LOOPS | | 140K| 11M| 1678 (1)| 00:00:21 |
|* 4 | INDEX RANGE SCAN | X1B | 1 | 53 | 3 (0)| 00:00:01 |
| 5 | TABLE ACCESS BY INDEX ROWID| T_OR_MON_ACTION | 140K| 4542K| 1675 (1)| 00:00:21 |
PLAN_TABLE_OUTPUT
|* 6 | INDEX RANGE SCAN | X3 | 140K| | 4 (25)| 00:00:01 |
|* 7 | INDEX RANGE SCAN | X4G | 4083 | | 22 (0)| 00:00:01 |
| 8 | TABLE ACCESS BY INDEX ROWID | T_OR_MON_ACTION_PARAM | 2 | 4428 | 52 (0)| 00:00:01 |
Predicate Information (identified by operation id):
4 - access("MESSAGE_ID"=4972102)
6 - access("SYS_ALIAS_0"."NESTED_TABLE_ID"="T_C_RMP_MNTRNG_XML_FULL_IL"."SYS_NC0001200013$")
7 - access("NESTED_TABLE_ID"="SYS_ALIAS_0"."SYS_NC0000500006$")
PLAN_TABLE_OUTPUT
Note
- dynamic sampling used for this statement (level=2)
When I run the query, the result comes back within 0.3 seconds.
Why is the explain plan off like that?
Is this just the way it is, or is there something going wrong here?This is my table create statement:
CREATE TABLE QQRCSBI0.T_C_RMP_MNTRNG_XML_FULL_IL (
MESSAGE_ID NUMBER(22,0) NOT NULL ENABLE,
XML_EVAL_ID NUMBER(22,0),
VIN7 VARCHAR2(7 BYTE),
FLEET_ID VARCHAR2(50 BYTE),
CSC_SW_VERSION VARCHAR2(100 BYTE),
RECEIVED DATE,
XML_CONTENT SYS.XMLTYPE ,
DWH_LM_TS_UTC DATE NOT NULL ENABLE,
CONSTRAINT PK_C_RMP_MNTRNG_XML_FULL_IL5 PRIMARY KEY (MESSAGE_ID)
) NOLOGGING TABLESPACE CATALOG
VARRAY "XML_CONTENT"."XMLDATA"."ACTION" STORE AS TABLE "T_OR_MON_ACTION" (
NOLOGGING TABLESPACE "CATALOG"
VARRAY "PARAM" STORE AS TABLE "T_OR_MON_ACTION_PARAM" (
NOLOGGING TABLESPACE "CATALOG"
) RETURN AS LOCATOR
) RETURN AS LOCATOR
XMLTYPE XML_CONTENT STORE AS OBJECT RELATIONAL XMLSCHEMA "http://mydomain.com/csc_monitoring_session.xsd" ELEMENT "monitoring";
I set all default table names in the schema to blank and registered the schema with genTables=false.
I am still running into problems retrieving the 3rd level T_OR_MON_ACTION_PARAM data. The query just crashes after a while because it is running out of either TEMP space or UNDO space (it keeps changing). I'll take a step back to re-evaluate and post another thread about that in a bit I guess...
You said "SQL*Plus explain plan, goes most of the time bananas" - is there a difference in what client (SqlPlus or SqlDeveloper) I use to get the explain plan? I thought the plan was generated by the DB and the clients just display the result, and the only difference is the way the clients display the plan?!
Maybe you are looking for
-
Need help connecting pritner to home network
Okay, here is the run down. I just created a home network with a Netgear wireless N router. I have an Airport Extreme Base Station (domed) that is connected to an HP inkjet printer, but not to either the router or the modem. Previous to the home n
-
IPhoto can't find my Library...
When I try to launch iPhoto, I get this: "Your photo library was not found. Do you want to find your iPhoto Library?" If I select "choose library," my pictures folder opens but there's nothing in it. And I don't want to create a new one because I hav
-
Collective Invoices Functionality (702)
Case 1: For multiple purchase order with service line items - after the confirmation is successfully posted and accepted by the buyer SUS allows to create one invoice for these purchase orders together. This scenario is fine. Case 2: (We don't have A
-
Additional Data B data not visible
Hi Firends, I have my data coming in Additional Data B at item level from a Z table. The scenario is for Credit notes. I have created debit notes copying credit notes document type, but the data is not coming in Additional Tab B. There are 2 client o
-
Hello, I have adobe photo cs5.....very old and had to buy a new computer as xp is no longer good...I bought bottom of the barrel as I cant afford anything. I am trying to download my CD of this to my new laptop and its not doing anything. I am able