Explain plan doubt.
I have done 'explain plan' for this query:-
explain plan for
select MD.* from ppbs_mobile_detail MD, ppbs_inv_sim_serial ISS where MD.LATEST_SIM_SERIAL_NO=ISS.SIM_SERIAL_NO
and MD.MOBILE_NO=ISS.MOBILE_NO
which is having indexes on all the four columns of the 2 tables used: LATEST_SIM_SERIAL_NO,SIM_SERIAL_NO,MOBILE_NO,
MOBILE_NO.
But only 1 index on mobile no. of ppbs_mobile_detail is firing.
Is that, indexes on only 1 table should fire.
I hope, my question is clear. Please help in solving the doubt.
Regards.
thanks for ur update.
i tried, @?/rdbms/admin/utlxplan.sql but it was giving a error like 'unable to open file "?/rdbms/admin/utlxplan.sql"'.
So, i re-created the table.
I gave both the analyze statements,
SQL> analyze table PPBS_INV_SIM_SERIAL compute statistics for table for all indexed columns for all indexes ;
SQL> analyze table PPBS_MOBILE_DETAIL compute statistics for table for all indexed columns for all indexes ;
Output of select * from TABLE(dbms_xplan.display) is:-
| Id | Operation | Name | Rows | Bytes | Cost |
| 0 | SELECT STATEMENT | | 1 | 164 | 21174 |
| 1 | HASH JOIN | | 1 | 164 | 21174 |
| 2 | TABLE ACCESS FULL | PPBS_INV_SIM_SERIAL | 3221K| 86M| 9772 |
| 3 | TABLE ACCESS FULL | PPBS_MOBILE_DETAIL | 1469K| 190M| 2718 |
Note: cpu costing is off, PLAN_TABLE' is old version
regards.
Similar Messages
-
Explain plan does not say anything about partition
Hello,
We have Oracle 11g database. And we have range partitioned a table. Now when I see explain plans for queries sometimes it says PARTITION RANGE ALL (when no filter), Some times PARTITION RANGE ITERATOR or PARTITION RANGE SINGLE or PARTITION RANGE JOIN FILTER etc. But sometimes it does not say any thing about partition.
Is the partition pruning being used? Since my understanding is that table is no more a monolithic sort of, but sort of table now has many tables for each partition.
So option is either scan all partition i.e display PARTITION RANGE ALL or scan some partitions, and display it in explain plan.
Am I thinking in wrong direction?
Please let me know.
Thank you,The only thing to do that makes sense is to back up all your data, erase the boot drive, reinstall and update the OS, then restore only your documents from backup and reinstall your third-party software from known-good copies.
Sadly, this is not practical at the current time. She is away from home, in a place with modem-speed internet access, without access to install media or her backups (which are on a hard drive at home.) I was able to operate on her machine by sshing in, and I did the best I could to remove the crap. The rest will have to wait until she gets back.
Here is something I found by googling:
http://nnrpanel.com/offlineAU.htm
Thank you, I will try them. I doubt they will know anything (since there are no Mac instructions on that page) but maybe they can at least send me to the US center. I have tried the US Nielsen Ratings contact form, three times now, but it appears that either they don't read it or they don't respond to it. It also has a maximum message size of about 250 characters.
I wonder if it may be related to one of those make money at home - be a secret shopper - review products at your leaisure and make a ton of moneydeals.
I would tend to doubt it, if only because they are clearly quite effective (or nobody would be running those ads) and yet nobody has reported this anywhere else that I can find.
I'm going to send some emails and see if I can find someone who knows something. -
Explain Plan of a query.
I want to know the concept of this 'Explain Plan' of a query & why it is used. Could u also give the syntax of how a explain plan for a query can be done. Please help in solving the doubt as it is urgent.
Hi,
set autotrace traceonly explain or
-- create your plan table in your schema (only once)
@ ?/rdbms/admin/utlxplan
-- populate the plan table for your select
explain plan for select ...;
-- display output out of the PLAN_TABLE
@ ?/rdbms/admin/ultxplsRegards
Laurent -
Any room for improvement for this query? Explain Plan attached.
Is there any room for improvement for this query? Table stats are up-to-date. Any suggestions Query rewrite, addition of indexes,...etc ??
select sum(CONF
when (cd.actl_qty - cd.total_alloc_qty - lsd.Q < 0) then
0
else
cd.actl_qty - cd.total_alloc_qty - lsd.Q
end)
from (select sum(reqd_qty) as Q, ITEM_ID as ITEM
from SHIP_DTL SD
where exists (select 1
from CONF_dtl
where CONF_nbr = '1'
and ITEM_id = SD.ITEM_id)
group by ITEM_id) lsd,
CONF_dtl cd
where lsd.ITEM = cd.ITEM_id
and cd.CONF_nbr = '1'Total number of rows in the tables involved
select count(*) from CONF_DTL;
COUNT(*)
1785889
select count(*) from shp_dtl;
COUNT(*)
286675
Explain Plan
PLAN_TABLE_OUTPUT
Plan hash value: 2325658044
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 39 | 4 (25)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 39 | | |
| 2 | VIEW | | 1 | 39 | 4 (25)| 00:00:01 |
| 3 | HASH GROUP BY | | 1 | 117 | 4 (25)| 00:00:01 |
| 4 | TABLE ACCESS BY INDEX ROWID | SHIP_DTL | 1 | 15 | 1 (0)| 00:00:01
| 5 | NESTED LOOPS | | 1 | 117 | 3 (0)| 00:00:01 |
| 6 | MERGE JOIN CARTESIAN | | 1 | 102 | 2 (0)| 00:00:01 |
| 7 | TABLE ACCESS BY INDEX ROWID | CONF_DTL | 1 | 70 | 1 (0)| 00:00:01 |
|* 8 | INDEX RANGE SCAN | PK_CONF_DTL | 1 | | 1 (0)| 00:00:01 |
| 9 | BUFFER SORT | | 1 | 32 | 1 (0)| 00:00:01 |
| 10 | SORT UNIQUE | | 1 | 32 | 1 (0)| 00:00:01 |
| 11 | TABLE ACCESS BY INDEX ROWID| CONF_DTL | 1 | 32 | 1 (0)| 00:00:01 |
|* 12 | INDEX RANGE SCAN | PK_CONF_DTL | 1 | | 1 (0)| 00:00:01 |
|* 13 | INDEX RANGE SCAN | SHIP_DTL_IND_6 | 1 | | 1 (0)| 00:00:01 |
Predicate Information (identified by operation id):
8 - access("CD"."CONF_NBR"='1')
12 - access("CONF_NBR"='1')
13 - access("ITEM_ID"="SD"."ITEM_ID")
filter("ITEM_ID"="CD"."ITEM_ID")Citizen_2 wrote:
Is there any room for improvement for this query? Table stats are up-to-date. Any suggestions Query rewrite, addition of indexes,...etc ??You say that the table stats are up-to-date, but is the following assumption of the optimizer correct:
select count(*)
from CONF_dtl
where CONF_nbr = '1';Does this query return a count of 1? I doubt that, but that's what Oracle estimates in the EXPLAIN PLAN output. Based on that assumption you get a cartesian join between the two CONF_DTL table instances, and the result - which is still expected to be one row at most - is then joined to the SHIP_DTL table using a NESTED LOOP.
If above assumption is incorrect, the number of rows generated by the cartesian join can be tremendous rendering the NESTED LOOP operation quite inefficient.
You can verify this by using the DBMS_XPLAN.DISPLAY_CURSOR function together with the GATHER_PLAN_STATISTICS hint, if you're already on 10g or later.
For more information regarding the DISPLAY_CURSOR function, see e.g. here: http://jonathanlewis.wordpress.com/2006/11/09/dbms_xplan-in-10g/
It will show you the actual cardinalities compared to the estimated cardinalities.
If the estimate of the optimizer is incorrect, you should find out why. There still might be some issues with the statistics, since this is most obvious reason for incorrect estimates.
Are your index statistics up-to-date?
Regards,
Randolf
Oracle related stuff blog:
http://oracle-randolf.blogspot.com/
SQLTools++ for Oracle (Open source Oracle GUI for Windows):
http://www.sqltools-plusplus.org:7676/
http://sourceforge.net/projects/sqlt-pp/ -
Explain Plan shows Nested Loops, Is it good or bad?
Hi All,
I have a doubt in the explain plan, I would like to know if the Nested Loops , will it degrade the query performance?
Note: I have pasted only few output that I had taken from the expalin plan.
Do let me know if there is any article I could read to get clear understanding about the same.
17 NESTED LOOPS ANTI Cost: 125 Bytes: 186 Cardinality: 1
15 NESTED LOOPS ANTI Cost: 124 Bytes: 166 Cardinality: 1
12 NESTED LOOPS Cost: 122 Bytes: 140 Cardinality: 1
9 NESTED LOOPS Cost: 121 Bytes: 117 Cardinality: 1
ThanksHi,
there is absolutely nothing wrong about nested loops (NL). It's a very efficient way of combining data from two rowsources. It works pretty much like a regular loop: it takes all rows from one rowsource (the "outer" one) and for each of them it looks up a row matching the join condition in the other rowsource (the "inner" one).
Note that there are not so many alternatives in Oracle: there are only 3 ways to join data in Oracle, and one of them is used in rather special circumstances (merge join). So normally the choice is between a NL and a hash join. Hash join (HJ) takes the smaller dataset and builds an in-memory lookup table using a hash function on join column(s). Then it goes through the other dataset and as it goes, it applies the hashing function to join column(s) and picks the matching rows from the smaller dataset.
Actually, hash joins and nested loops are not all that different. The basic mechanism is same: you go through one datasource and as you go, you pick matching rows from the other and do the join. The main difference is that a HJ requires some preparation work (it costs resources to build the in-memory table) and thus HJ are typically associated with less-selective queries and full table scans.
In your particular case it's nor possible to tell whether or not NL is in order based on just a few rows from the explain plan. We need to know the structure of your tables (the DDL), what kind of data they hold (optimizer stats) and what query you are running to be able to tell.
Best regards,
Nikolay -
Calculating the Size(KB) in the explain plan....
Hi
I executed a sql statement in SQL*PLUS and having enabled the tracing in OEM , among others , I read the Size in KiloBytes which the 'TABLE ACCESS FULL' segment of the explain plan returned.....
This number is 5.998,193KB
I used the vsize built-in function in order to get the total number in bytes of the physical representation of all the rows (about 53500) ....
So , I wrote :
select nvl(sum(vsize(farmak_code)),0)+nvl(sum(vsize(emp_name)),0)+nvl(sum(vsize(category)),0)+ .....+.....
from mitroo_farmakou
The result was 5794544 in bytes which is close to 5.998,193KB.
My question is :
The computation of the bytes in the explain plan (TABLE ACCESS FULL segment) is done by adding the vsize of all columns....????
Does anybody Knows...????
Thanks , a lot
SimonI doubt it. For a large table that would be an incredibly expensive calculation.
I suspect that it is something closer to:
SQL> SELECT * FROM incident;
Execution Plan
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=137 Card=15603 Bytes=6818511)
1 0 TABLE ACCESS (FULL) OF 'INCIDENT' (Cost=137 Card=15603 Bytes=6818511)
SQL> SELECT ROUND(num_rows * avg_row_len)
2 FROM user_tables
3 WHERE table_name = 'INCIDENT';
ROUND(NUM_ROWS*AVG_ROW_LEN)
6818449HTH
John -
Why the explain plan incorrent?
I have a sql in oracle10.2.03:
select *
from (select a.*
from t_user a, t_message b
where b.user_id = a.row_id and a.user_type = 1
order by b.happen_time desc)
where rownum <= 5
there are indexes on column a.user_type,b.user_id,b.happen_time, and has been analyzed. a.user_type=1 only have 1/1000 records
the explain plan is below:
cost Cardinary Bytes
SELECT STATEMENT, GOAL = ALL_ROWS 30 5 3790
COUNT STOPKEY
VIEW BMTEST 30 6 4548
NESTED LOOPS 30 6 1158
TABLE ACCESS BY INDEX ROWID BMTEST T_MESSAGE 13 1524118 24385888
INDEX FULL SCAN DESCENDING BMTEST IDX_MESSAGE_2 1 168
TABLE ACCESS BY INDEX ROWID BMTEST T_USER 1 1 177
INDEX UNIQUE SCAN BMTEST PK_USER 1 1
Oracle use the index full scan descending on the happen_time. the cost only has 30.
After I add hint on the sql on the user_id of t_message
select *
from (select /*+index (b idx_message_1)*/ a.*
from t_user a, t_message b
where b.user_id = a.row_id and a.user_type = 1
order by b.happen_time desc)
where rownum <= 5
the explain plan change to:
cost Cardinary Bytes
SELECT STATEMENT, GOAL = ALL_ROWS 5020 5 3790
COUNT STOPKEY
VIEW BMTEST 5020 54707 41467906
SORT ORDER BY STOPKEY 5020 54707 10558451
TABLE ACCESS BY INDEX ROWID BMTEST T_MESSAGE 26 515 8240
NESTED LOOPS 2707 54707 10558451
TABLE ACCESS BY INDEX ROWID BMTEST T_USER 1 106 18762
INDEX RANGE SCAN BMTEST IDX_USER_2 1 106
INDEX RANGE SCAN BMTEST IDX_MESSAGE_1 1 515
INDEX UNIQUE SCAN BMTEST PK_USER 1 1
The cost is 5020, but the execute usage time only is 100ms, and the first SQL does not add hint usage 20s.
Why the lower cost waste more time, if the cost caculate is incorrect?
Edited by: [email protected] on Sep 11, 2008 9:14 PM[email protected] wrote:
But i am afraid i use a misunderstand title for this post,my doubt is why oracle get a large cost with the sql execute few time but get a small cost with the sql execute long time.The cost of a query isn't a particularly good proxy for runtime. It is perfectly reasonable for a query with a cost of 1000 to run more quickly than a query with a cost of 100. The cost of queries is only directly comparable between different plans in the same 10053 trace file.
[email protected] wrote:
All the indexed columns are both analyzed by the command or by DBMS_STATS package and the cpu costing is enabled.But what order are the commands being run? And why is the ANALYZE command being used to gather optimizer stats.
In the first plan:
INDEX FULL SCAN DESCENDING BMTEST IDX_MESSAGE_2 1 168
Why this index full scan cost only 1? how did oracle get this number? Is there formula to caculate the cost of index full scan? I have read the article named "Cost Based Oracle Fundamentals" and there is no introduce how to caculate it.
I think this abnormality cost makes the cost of next step "NESTED LOOPS" very smal and finally lead this abnormality result.1) Which article are you talking about? Are you talking about Jonathan Lewis's book "Cost Based Oracle Fundamentals"? Or are you referring to a different article somewhere?
2) Can you post the query plans formatted via DBMS_XPLAN.DISPLAY (including the predicate information and enclose the output in the \[pre\] and \[pre\] tags to preserve white space?
Justin
Justin -
Hi Experts,
I got a doubt regarding the Explain Plan.
Is there any relation between the Cost shown in Explain Plan and the no of rows fetched by the query ?
In other words - If the no of rows fetched by query increases, will that increase the cost also?
Can anybody please provide me some pointers on this?
Thanks & Regards,
Ranit B.ranitB wrote:
Hi Experts,
I got a doubt regarding the Explain Plan.
Is there any relation between the Cost shown in Explain Plan and the no of rows fetched by the query ?
In other words - If the no of rows fetched by query increases, will that increase the cost also?
Can anybody please provide me some pointers on this?The answer would be "not really" as the cost is single block read seek time from disk" . But if the number of rows which are expected+ to come in the result set are higher, the work done expected by Oracle would also be higher. So in an indirect way, the answer can be yes. That said, the number of rows which are shown in the explain plan (you should check the execution plan, explain plan is not the real plan) are the rows that the optimizer is expecting to fetch and the actual number ofrows fetched may or may not match with it.
Aman.... -
I wrote a SQL in Oracle EBS, please see the following:
SELECT msi.segment1 item_num, mmt.revision revision,
msi.description description_en,
msi_tl.long_description description_cn,
mmt.transfer_organization_id mfg_org_id,
xxuts_inv_trh_pkg.get_organization_name(mmt.transfer_organization_id),
mmt.subinventory_code subinv, mmt.locator_id,
mtln.lot_number lot_num, mmt.transaction_id txn_id,
mmt.transfer_subinventory co_subinv, mmt.transfer_locator_id,
mmt.transaction_date txn_date, fn.user_name user_name,
mts.transaction_source_type_name txn_source_type,
wie.wip_entity_name order_num,
xxuts_inv_trh_pkg.get_qty_before (mmt.organization_id,
mmt.inventory_item_id,
mmt.revision,
mmt.subinventory_code,
mmt.transaction_id,
mmt.transaction_date
DECODE (msi.lot_control_code,
2, mtln.transaction_quantity,
mmt.transaction_quantity
) txn_qty,
mtt.transaction_type_name txn_type, mmt.actual_cost item_cost,
DECODE (msi.lot_control_code,
2, mtln.transaction_quantity,
mmt.transaction_quantity
* mmt.actual_cost amount,
mtln.primary_quantity primary_qty,
NVL
(mtr.reason_name,
(SELECT mtrh.attribute1 || mtrh.attribute2 || mtrh.attribute3
FROM mtl_txn_request_headers mtrh
WHERE EXISTS (
SELECT 'X'
FROM mtl_txn_request_lines mtrl
WHERE mtrh.header_id = mtrl.header_id
AND mtrl.transaction_header_id =
mmt.transaction_set_id
AND mtrl.txn_source_id = mmt.transaction_source_id
AND mtrl.line_id = mmt.source_line_id))
) reason,
mmt.transaction_reference REFERENCE
FROM mtl_system_items_b msi --250,
mtl_system_items_tl msi_tl --500,
mtl_transaction_lot_numbers mtln -210,
mtl_material_transactions mmt -333,
mtl_transaction_types mtt,
mtl_txn_source_types mts,
mtl_item_categories mic -800,
mtl_transaction_reasons mtr,
fnd_user fn,
wip_entities wie --5
WHERE msi.inventory_item_id = mmt.inventory_item_id
AND msi.inventory_item_id = msi_tl.inventory_item_id
AND msi.organization_id = msi_tl.organization_id
AND mtr.reason_id(+) = mmt.reason_id
AND msi_tl.LANGUAGE = USERENV ('LANG')
AND mmt.transaction_id = mtln.transaction_id(+)
AND mic.inventory_item_id = mmt.inventory_item_id
AND mic.organization_id = mmt.organization_id
AND mic.category_set_id = :b15
AND mmt.transaction_type_id = mtt.transaction_type_id
AND mmt.transaction_source_type_id = mts.transaction_source_type_id
AND msi.organization_id = mmt.organization_id
AND mmt.transaction_source_id = wie.wip_entity_id
AND mmt.transaction_source_type_id IN (5)
AND fn.user_id = mmt.created_by
AND mmt.organization_id = :b14
AND msi.segment1 >= NVL (:b13, msi.segment1)
AND msi.segment1 <= NVL (:b12, msi.segment1)
AND NVL (mmt.revision, '-99') = NVL (NVL (:b11, mmt.revision), '-99')
AND mmt.subinventory_code >= NVL (:b10, mmt.subinventory_code)
AND mmt.subinventory_code <= NVL (:b9, mmt.subinventory_code)
AND mmt.transaction_date BETWEEN :b8 AND :b7
AND mmt.creation_date BETWEEN :b6 AND :b5
AND mmt.transaction_type_id = NVL (:b4, mmt.transaction_type_id)
AND mmt.transaction_source_type_id = NVL (:b3, mmt.transaction_source_type_id)
AND mmt.transaction_id = NVL (:b2, mmt.transaction_id)
AND fn.user_id = NVL (:b1, fn.user_id)
It's explain plan is:
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | INSERT STATEMENT | | | | 33 (100)| |
| 1 | CONCATENATION | | | | | |
|* 2 | FILTER | | | | | |
| 3 | NESTED LOOPS | | 1 | 312 | 17 (0)| 00:00:01 |
| 4 | NESTED LOOPS | | 1 | 297 | 15 (0)| 00:00:01 |
| 5 | NESTED LOOPS OUTER | | 1 | 282 | 13 (0)| 00:00:01 |
| 6 | NESTED LOOPS | | 1 | 257 | 10 (0)| 00:00:01 |
| 7 | NESTED LOOPS | | 1 | 188 | 8 (0)| 00:00:01 |
| 8 | NESTED LOOPS | | 1 | 174 | 7 (0)| 00:00:01 |
| 9 | NESTED LOOPS | | 1 | 148 | 6 (0)| 00:00:01 |
| 10 | NESTED LOOPS OUTER | | 1 | 128 | 5 (0)| 00:00:01 |
| 11 | NESTED LOOPS | | 1 | 108 | 4 (0)| 00:00:01 |
| 12 | TABLE ACCESS BY INDEX ROWID| MTL_TXN_SOURCE_TYPES | 1 | 18 | 1 (0)| 00:00:01 |
|* 13 | INDEX UNIQUE SCAN | MTL_TXN_SOURCE_TYPES_U1 | 1 | | 0 (0)| |
|* 14 | TABLE ACCESS BY INDEX ROWID| MTL_MATERIAL_TRANSACTIONS | 1 | 90 | 3 (0)| 00:00:01 |
|* 15 | INDEX RANGE SCAN | MTL_MATERIAL_TRANSACTIONS_N8 | 1 | | 2 (0)| 00:00:01 |
| 16 | TABLE ACCESS BY INDEX ROWID | MTL_TRANSACTION_REASONS | 1 | 20 | 1 (0)| 00:00:01 |
|* 17 | INDEX UNIQUE SCAN | MTL_TRANSACTION_REASONS_U1 | 1 | | 0 (0)| |
| 18 | TABLE ACCESS BY INDEX ROWID | WIP_ENTITIES | 1 | 20 | 1 (0)| 00:00:01 |
|* 19 | INDEX UNIQUE SCAN | WIP_ENTITIES_U1 | 1 | | 0 (0)| |
| 20 | TABLE ACCESS BY INDEX ROWID | MTL_TRANSACTION_TYPES | 1 | 26 | 1 (0)| 00:00:01 |
|* 21 | INDEX UNIQUE SCAN | MTL_TRANSACTION_TYPES_U1 | 1 | | 0 (0)| |
| 22 | TABLE ACCESS BY INDEX ROWID | FND_USER | 1 | 14 | 1 (0)| 00:00:01 |
|* 23 | INDEX UNIQUE SCAN | FND_USER_U1 | 1 | | 0 (0)| |
|* 24 | TABLE ACCESS BY INDEX ROWID | MTL_SYSTEM_ITEMS_B | 1 | 69 | 2 (0)| 00:00:01 |
|* 25 | INDEX UNIQUE SCAN | MTL_SYSTEM_ITEMS_B_U1 | 1 | | 1 (0)| 00:00:01 |
| 26 | TABLE ACCESS BY INDEX ROWID | MTL_TRANSACTION_LOT_NUMBERS | 1 | 25 | 3 (0)| 00:00:01 |
|* 27 | INDEX RANGE SCAN | MTL_TRANSACTION_LOT_NUMBERS_N1 | 1 | | 2 (0)| 00:00:01 |
|* 28 | INDEX RANGE SCAN | MTL_ITEM_CATEGORIES_U1 | 1 | 15 | 2 (0)| 00:00:01 |
| 29 | TABLE ACCESS BY INDEX ROWID | MTL_SYSTEM_ITEMS_TL | 1 | 15 | 2 (0)| 00:00:01 |
|* 30 | INDEX UNIQUE SCAN | MTL_SYSTEM_ITEMS_TL_U1 | 1 | | 1 (0)| 00:00:01 |
|* 31 | FILTER | | | | | |
| 32 | NESTED LOOPS OUTER | | 1 | 312 | 16 (0)| 00:00:01 |
| 33 | NESTED LOOPS | | 1 | 287 | 13 (0)| 00:00:01 |
| 34 | NESTED LOOPS | | 1 | 272 | 11 (0)| 00:00:01 |
| 35 | NESTED LOOPS | | 1 | 257 | 9 (0)| 00:00:01 |
| 36 | NESTED LOOPS | | 1 | 188 | 7 (0)| 00:00:01 |
| 37 | NESTED LOOPS OUTER | | 1 | 162 | 6 (0)| 00:00:01 |
| 38 | NESTED LOOPS | | 1 | 142 | 5 (0)| 00:00:01 |
| 39 | NESTED LOOPS | | 1 | 128 | 4 (0)| 00:00:01 |
| 40 | NESTED LOOPS | | 1 | 108 | 3 (0)| 00:00:01 |
| 41 | TABLE ACCESS BY INDEX ROWID| MTL_TXN_SOURCE_TYPES | 1 | 18 | 1 (0)| 00:00:01 |
|* 42 | INDEX UNIQUE SCAN | MTL_TXN_SOURCE_TYPES_U1 | 1 | | 0 (0)| |
|* 43 | TABLE ACCESS BY INDEX ROWID| MTL_MATERIAL_TRANSACTIONS | 1 | 90 | 2 (0)| 00:00:01 |
|* 44 | INDEX UNIQUE SCAN | MTL_MATERIAL_TRANSACTIONS_U1 | 1 | | 1 (0)| 00:00:01 |
| 45 | TABLE ACCESS BY INDEX ROWID | WIP_ENTITIES | 48143 | 940K| 1 (0)| 00:00:01 |
|* 46 | INDEX UNIQUE SCAN | WIP_ENTITIES_U1 | 1 | | 0 (0)| |
| 47 | TABLE ACCESS BY INDEX ROWID | FND_USER | 1 | 14 | 1 (0)| 00:00:01 |
|* 48 | INDEX UNIQUE SCAN | FND_USER_U1 | 1 | | 0 (0)| |
| 49 | TABLE ACCESS BY INDEX ROWID | MTL_TRANSACTION_REASONS | 36 | 720 | 1 (0)| 00:00:01 |
|* 50 | INDEX UNIQUE SCAN | MTL_TRANSACTION_REASONS_U1 | 1 | | 0 (0)| |
| 51 | TABLE ACCESS BY INDEX ROWID | MTL_TRANSACTION_TYPES | 98 | 2548 | 1 (0)| 00:00:01 |
|* 52 | INDEX UNIQUE SCAN | MTL_TRANSACTION_TYPES_U1 | 1 | | 0 (0)| |
|* 53 | TABLE ACCESS BY INDEX ROWID | MTL_SYSTEM_ITEMS_B | 297 | 20493 | 2 (0)| 00:00:01 |
|* 54 | INDEX UNIQUE SCAN | MTL_SYSTEM_ITEMS_B_U1 | 1 | | 1 (0)| 00:00:01 |
| 55 | TABLE ACCESS BY INDEX ROWID | MTL_SYSTEM_ITEMS_TL | 96026 | 1406K| 2 (0)| 00:00:01 |
|* 56 | INDEX UNIQUE SCAN | MTL_SYSTEM_ITEMS_TL_U1 | 1 | | 1 (0)| 00:00:01 |
|* 57 | INDEX RANGE SCAN | MTL_ITEM_CATEGORIES_U1 | 1 | 15 | 2 (0)| 00:00:01 |
| 58 | TABLE ACCESS BY INDEX ROWID | MTL_TRANSACTION_LOT_NUMBERS | 1 | 25 | 3 (0)| 00:00:01 |
|* 59 | INDEX RANGE SCAN | MTL_TRANSACTION_LOT_NUMBERS_N1 | 1 | | 2 (0)| 00:00:01 |
Predicate Information (identified by operation id):
2 - filter((:B6<=:B5 AND :B8<=:B7 AND :B2 IS NULL))
13 - access("MTS"."TRANSACTION_SOURCE_TYPE_ID"=5)
14 - filter(("MMT"."TRANSACTION_SOURCE_ID" IS NOT NULL AND
"MMT"."TRANSACTION_TYPE_ID"=NVL(:B4,"MMT"."TRANSACTION_TYPE_ID") AND
"MMT"."SUBINVENTORY_CODE">=NVL(:B10,"MMT"."SUBINVENTORY_CODE") AND
"MMT"."SUBINVENTORY_CODE"<=NVL(:B9,"MMT"."SUBINVENTORY_CODE") AND
NVL("MMT"."REVISION",'-99')=NVL(NVL(:B11,"MMT"."REVISION"),'-99') AND "MMT"."TRANSACTION_ID" IS NOT NULL AND
"MMT"."CREATION_DATE">=:B6 AND "MMT"."CREATION_DATE"<=:B5))
15 - access("MMT"."TRANSACTION_SOURCE_TYPE_ID"=5 AND "MMT"."ORGANIZATION_ID"=:B14 AND
"MMT"."TRANSACTION_DATE">=:B8 AND "MMT"."TRANSACTION_DATE"<=:B7)
filter(NVL(:B3,"MMT"."TRANSACTION_SOURCE_TYPE_ID")=5)
17 - access("MTR"."REASON_ID"="MMT"."REASON_ID")
19 - access("MMT"."TRANSACTION_SOURCE_ID"="WIE"."WIP_ENTITY_ID")
21 - access("MMT"."TRANSACTION_TYPE_ID"="MTT"."TRANSACTION_TYPE_ID")
23 - access("FN"."USER_ID"="MMT"."CREATED_BY")
filter("FN"."USER_ID"=NVL(:B1,"FN"."USER_ID"))
24 - filter(("MSI"."SEGMENT1">=NVL(:B13,"MSI"."SEGMENT1") AND "MSI"."SEGMENT1"<=NVL(:B12,"MSI"."SEGMENT1")))
25 - access("MSI"."INVENTORY_ITEM_ID"="MMT"."INVENTORY_ITEM_ID" AND "MSI"."ORGANIZATION_ID"=:B14)
27 - access("MMT"."TRANSACTION_ID"="MTLN"."TRANSACTION_ID")
28 - access("MIC"."ORGANIZATION_ID"=:B14 AND "MIC"."INVENTORY_ITEM_ID"="MMT"."INVENTORY_ITEM_ID" AND
"MIC"."CATEGORY_SET_ID"=:B15)
30 - access("MSI"."INVENTORY_ITEM_ID"="MSI_TL"."INVENTORY_ITEM_ID" AND "MSI_TL"."ORGANIZATION_ID"=:B14 AND
"MSI_TL"."LANGUAGE"=USERENV('LANG'))
31 - filter((:B6<=:B5 AND :B8<=:B7 AND :B2 IS NOT NULL))
42 - access("MTS"."TRANSACTION_SOURCE_TYPE_ID"=5)
43 - filter(("MMT"."TRANSACTION_SOURCE_ID" IS NOT NULL AND "MMT"."TRANSACTION_DATE">=:B8 AND
"MMT"."ORGANIZATION_ID"=:B14 AND "MMT"."TRANSACTION_SOURCE_TYPE_ID"=5 AND
NVL(:B3,"MMT"."TRANSACTION_SOURCE_TYPE_ID")=5 AND "MMT"."TRANSACTION_TYPE_ID"=NVL(:B4,"MMT"."TRANSACTION_TYPE_ID"
) AND "MMT"."SUBINVENTORY_CODE">=NVL(:B10,"MMT"."SUBINVENTORY_CODE") AND
"MMT"."SUBINVENTORY_CODE"<=NVL(:B9,"MMT"."SUBINVENTORY_CODE") AND
NVL("MMT"."REVISION",'-99')=NVL(NVL(:B11,"MMT"."REVISION"),'-99') AND "MMT"."TRANSACTION_DATE"<=:B7 AND
"MMT"."CREATION_DATE">=:B6 AND "MMT"."CREATION_DATE"<=:B5))
44 - access("MMT"."TRANSACTION_ID"=:B2)
46 - access("MMT"."TRANSACTION_SOURCE_ID"="WIE"."WIP_ENTITY_ID")
48 - access("FN"."USER_ID"="MMT"."CREATED_BY")
filter("FN"."USER_ID"=NVL(:B1,"FN"."USER_ID"))
50 - access("MTR"."REASON_ID"="MMT"."REASON_ID")
52 - access("MMT"."TRANSACTION_TYPE_ID"="MTT"."TRANSACTION_TYPE_ID")
53 - filter(("MSI"."SEGMENT1">=NVL(:B13,"MSI"."SEGMENT1") AND "MSI"."SEGMENT1"<=NVL(:B12,"MSI"."SEGMENT1")))
54 - access("MSI"."INVENTORY_ITEM_ID"="MMT"."INVENTORY_ITEM_ID" AND "MSI"."ORGANIZATION_ID"=:B14)
56 - access("MSI"."INVENTORY_ITEM_ID"="MSI_TL"."INVENTORY_ITEM_ID" AND "MSI_TL"."ORGANIZATION_ID"=:B14 AND
"MSI_TL"."LANGUAGE"=USERENV('LANG'))
57 - access("MIC"."ORGANIZATION_ID"=:B14 AND "MIC"."INVENTORY_ITEM_ID"="MMT"."INVENTORY_ITEM_ID" AND
"MIC"."CATEGORY_SET_ID"=:B15)
59 - access("MMT"."TRANSACTION_ID"="MTLN"."TRANSACTION_ID")
I am doubt why to perform two times explain plan(Predicate -2 and 31).
ThanksTom.lai wrote:
I wrote a SQL in Oracle EBS, please see the following:
AND msi.segment1 >= NVL (:b13, msi.segment1)
AND msi.segment1 <= NVL (:b12, msi.segment1)
AND NVL (mmt.revision, '-99') = NVL (NVL (:b11, mmt.revision), '-99')
AND mmt.subinventory_code >= NVL (:b10, mmt.subinventory_code)
AND mmt.subinventory_code <= NVL (:b9, mmt.subinventory_code)
AND mmt.transaction_date BETWEEN :b8 AND :b7
AND mmt.creation_date BETWEEN :b6 AND :b5
AND mmt.transaction_type_id = NVL (:b4, mmt.transaction_type_id)
AND mmt.transaction_source_type_id = NVL (:b3, mmt.transaction_source_type_id)
AND mmt.transaction_id = NVL (:b2, mmt.transaction_id)
AND fn.user_id = NVL (:b1, fn.user_id)I am doubt why to perform two times explain plan(Predicate -2 and 31).Using your NVL expressions above you've hit a special implementation for this particular construct in the Oracle optimizer, for more information, see here:
http://jonathanlewis.wordpress.com/2007/01/09/conditional-sql/
http://jonathanlewis.wordpress.com/2007/02/14/conditional-sql-2/
This splits your plan into two plans for the two cases possible, and depending on if the value passed is NULL or not only one of the branches will actually get executed.
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/ -
Query tunning in Oracle using Explain Plan
Adding to my below question: I have now modified the query and the path shownby 'Explain plan' has reduced. The 'Time' column of plan_table is also showing much lesser value. However, some people are suggesting me to consider the time required by the query to execute on Toad. Will it be practical? Please help!!
Hi, I am using Oracle 11g. I need to optimize a Select query(Need to minimize the execution time). I need to know how 'Explain Plan' would help me. I know how to use Explain Plan command. I refer Plan_table table to see the details of the plan. Please guide me regarding which columns of the Plan_table should be considered while modifying the query for optimization. Some people say, 'Time' column should be considered, some say 'Bytes' etc. Some suggest on minimizing the full table scans, while some people say that I should minimize the total no. operations (less no. of rows should be displayed in Plan_table). As per an experienced friend of mine, full table scans should be reduced (for e.g. if there are 5 full table scans in the plan, then try to reduce them to less than 5. ). However, if I consider any full table scan operation in the plan_table, its shows value of 'time' column as only 1 which is very very less. Does this mean the full scan is actually taking very less time?? If yes, then this means full table scans are very fast in my case and no need to work on them. Some articles suggest that plan shown by 'Explain Plan' command is not necessarily followed while executing the query. So what should I look for then? How should I optimize the query and how will I come to know that it's optimized?? Please help!!...
Edited by: 885901 on Sep 20, 2011 2:10 AM885901 wrote:
Hi, I am using Oracle 11g. I need to optimize a Select query(Need to minimize the execution time). I need to know how 'Explain Plan' would help me. I know how to use Explain Plan command. I refer Plan_table table to see the details of the plan. Please guide me regarding which columns of the Plan_table should be considered while modifying the query for optimization. Some people say, 'Time' column should be considered, some say 'Bytes' etc. Some suggest on minimizing the full table scans, while some people say that I should minimize the total no. operations (less no. of rows should be displayed in Plan_table). As per an experienced friend of mine, full table scans should be reduced (for e.g. if there are 5 full table scans in the plan, then try to reduce them to less than 5. ). However, if I consider any full table scan operation in the plan_table, its shows value of 'time' column as only 1 which is very very less. Does this mean the full scan is actually taking very less time?? If yes, then this means full table scans are very fast in my case and no need to work on them. Some articles suggest that plan shown by 'Explain Plan' command is not necessarily followed while executing the query. So what should I look for then? How should I optimize the query and how will I come to know that it's optimized?? Please help!!...how fast is fast enough? -
Problems with explain plan and statement
Hi community,
I have migrated a j2ee application from DB2 to Oracle.
First some facts of our application and database instance:
We are using oracle version 10.2.0.3 and driver version 10.2.0.3. It runs with charset Unicode 3.0 UTF-8.
Our application is using Tomcat as web container and jboss as application server. We are only using prepared statements. So if I talk about statements I always mean prepared statements. Also our application is setting the defaultNChar property to true because every char and varchar field has been created as an nchar and nvarchar.
We have some jsp sites that contains lists with search forms. Everytime I enter a value to the form that returns a filled resultset, the lists are performing great. But everytime I enter a value that returns an empty resultset, the lists are 100 times slower. The jsp sites are running in the tomcat environment and submitting their statements directly to the database. The connections are pooled by dbcp. So what can cause this behaviour??
To anaylze this problem I started logging all statements and filled-in search field values and combinations that are executed by the lists described above. I also developed a standalone helper tool that reads the logged statements, executes them to the database and generates an explain plan for every statement. But now there appears a strange situation. Every statement, that performs really fast within our application, is now executed by the helper tool extremely slow. So I edited some jsp pages within our application to force an explain plan from there (tomcat env). So when I'm executing the same statement I'm getting with the exactly same code two completely different explain plans.
First the statement itself:
select LINVIN.BBASE , INVINNUM , INVINNUMALT , LINVIN.LSUPPLIERNUM , LSUPPLIERNUMEXT , LINVIN.COMPANYCODE , ACCOUNT , INVINTXT , INVINSTS , INVINTYP , INVINDAT , RECEIPTDAT , POSTED , POSTINGDATE , CHECKCOSTCENTER , WORKFLOWIDEXT , INVINREFERENCE , RESPONSIBLEPERS , INVINSUM_V , INVINSUMGROSS_V , VOUCHERNUM , HASPOSITIONS , PROCESSINSTANCEID , FCURISO_V , LSUPPLIER.AADDRLINE1 from LINVIN, LSUPPLIER where LINVIN.BBASE = LSUPPLIER.BBASE and LINVIN.LSUPPLIERNUM = LSUPPLIER.LSUPPLIERNUM and LINVIN.BBASE = ? order by LINVIN.BBASE, INVINDAT DESC
Now the explain plan from our application:
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 101 | 28583 | 55 (0)| 00:00:01 |
| 1 | NESTED LOOPS | | 101 | 28583 | 55 (0)| 00:00:01 |
| 2 | TABLE ACCESS BY INDEX ROWID| LINVIN | 93709 | 12M| 25 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | LINV_INVDAT | 101 | | 1 (0)| 00:00:01 |
| 4 | TABLE ACCESS BY INDEX ROWID| LSUPPLIER | 1 | 148 | 1 (0)| 00:00:01 |
|* 5 | INDEX UNIQUE SCAN | PK_177597 | 1 | | 1 (0)| 00:00:01 |
Predicate Information (identified by operation id):
3 - access("LINVIN"."BBASE"=:1)
filter("LINVIN"."BBASE"=:1)
5 - access("LSUPPLIER"."BBASE"=:1 AND "LINVIN"."LSUPPLIERNUM"="LSUPPLIER"."LSUPPLIERNUM")
Now the one from the standalone tool:
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 93773 | 25M| | 12898 (1)| 00:02:35 |
| 1 | SORT ORDER BY | | 93773 | 25M| 61M| 12898 (1)| 00:02:35 |
|* 2 | HASH JOIN | | 93773 | 25M| 2592K| 7185 (1)| 00:01:27 |
| 3 | TABLE ACCESS BY INDEX ROWID| LSUPPLIER | 16540 | 2390K| | 332 (0)| 00:00:04 |
|* 4 | INDEX RANGE SCAN | LSUPPLIER_HAS_BASE_FK | 16540 | | | 11 (0)| 00:00:01 |
| 5 | TABLE ACCESS BY INDEX ROWID| LINVIN | 93709 | 12M| | 6073 (1)| 00:01:13 |
|* 6 | INDEX RANGE SCAN | LINVOICE_BMDT_FK | 93709 | | | 84 (2)| 00:00:02 |
Predicate Information (identified by operation id):
2 - access("LINVIN"."BBASE"="LSUPPLIER"."BBASE" AND "LINVIN"."LSUPPLIERNUM"="LSUPPLIER"."LSUPPLIERNUM")
4 - access("LSUPPLIER"."BBASE"=:1)
6 - access("LINVIN"."BBASE"=:1)
The size of the tables are: LINVIN - 383.692 Rows, LSUPPLIER - 115.782 Rows
As you can see the one executed from our application is much faster than the one from the helper tool. So why picks oracle a completely different explain plan for the same statement? An why is a hash join much slower than a nested loop? Because If I'm right a nested loop should only be used when the tables are pretty small..
I also tried to play with some parameters:
I set optimizer_index_caching to 100 and optimizer_index_cost_adj to 30. I also changed optimizer_mode to FIRST_ROWS_100.
I would really appreciated, if somebody can help me with this issue, because I'm really getting more and more distressed...
Thanks in advance,
Tobias
Edited by: tobiwan on Sep 3, 2008 11:49 PM
Edited by: tobiwan on Sep 3, 2008 11:50 PM
Edited by: tobiwan on Sep 4, 2008 12:01 AM
Edited by: tobiwan on Sep 4, 2008 12:02 AM
Edited by: tobiwan on Sep 4, 2008 12:04 AM
Edited by: tobiwan on Sep 4, 2008 12:06 AM
Edited by: tobiwan on Sep 4, 2008 12:06 AM
Edited by: tobiwan on Sep 4, 2008 12:07 AMtobiwan wrote:
Hi again,
Here ist the answer:
The problem, because I got two different explain plans, was that the external tool uses the NLS sesssion parameters coming from the OS which are in my case "de/DE".
Within our application these parameters are changed to "en/US"!! So if I'm calling in my external tool the java function Locale.setDefault(new Locale("en","US")) before connecting to the database the explain plans are finally equal.That might explain why you got two different execution plan, because one plan was obviously able to avoid a SORT ORDER BY operation, whereas the second plan required to run SORT ORDER BY operation, obviously because of the different NLS_SORT settings. An index by default uses the NLS_SORT = 'binary' order whereas ORDER BY obeys the NLS_SORT setting, which probably was set to 'GERMAN' in your "external tool" case. You can check the "NLS_SESSION_PARAMETERS" view to check your current NLS_SORT setting.
For more information regarding this issue, see my blog note I've written about this some time ago:
http://oracle-randolf.blogspot.com/2008/09/getting-first-rows-of-large-sorted.html
Now let me make a guess why you observe the behaviour that it takes so long if your result set is empty:
The plan avoiding the SORT ORDER BY is able to return the first rows of the result set very quickly, but could take quite a while until all rows are processed, since it requires potentially a lot of iterations of the loop until everything has been processed. Your front end probably by default only display the first n rows of the result set and therefore works fine with this execution plan.
Now if the result set is empty, depending on your data, indexes and search criteria, Oracle has to work through all the data using the inefficient NESTED LOOP approach only to find out that no data has been found, and since your application attempts to fetch the first n records, but no records will be found, it has to wait until all data has been processed.
You can try to reproduce this by deliberately fetching all records of a query that returns data and that uses the NESTED LOOP approach... It probably takes as long as in the case when no records are found.
Note that you seem to use bind variables and 10g, therefore you might be interested that due to the "bind variable peeking" functionality you might potentially end up with "unstable" plans depending on the values "peeked" when the statement is parsed.
For more information, see this comprehensive description of the issue:
http://www.pythian.com/blogs/867/stabilize-oracle-10gs-bind-peeking-behaviour-by-cutting-histograms
Note that this changes in 11g with the introduction of the "Adaptive Cursor Sharing".
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/ -
Cpu time is not getting displayed in explain plan
Hi All,
I am trying to analyze one query using explain plan .like below
1) explain plan for
SELECT /*+ parallel(tsp,8) use_hash( tsp tp) */ count(1)
FROM router tp,
receiver tsp
WHERE tp.rs = tsp.rp
AND creater_date >=to_date('04032009000000','ddmmyyyyhh24miss')
and tsp.XVF is not null
and tp.XVF is not null
and tp.role_name='BR';
2)@$ORACLE_HOME/rdbms/admin/utlxpls.sql
But i am getting only following columns in result .
| Id | Operation | Name | Rows | Bytes | Cost |
No Cpu time preset .
How can i extimate CPU time ?
Pls help
Thanksam_73798 wrote:
I am trying to analyze one query using explain plan .like below
But i am getting only following columns in result .
| Id | Operation | Name | Rows | Bytes | Cost |
No Cpu time preset .
How can i extimate CPU time ?You need to mention your database version (4-digits, e.g. 9.2.0.8).
In Oracle 9i CPU costing is disabled by default, you need to gather WORKLOAD system statistics to enable the CPU costing.
In 10g CPU costing is enabled by default and uses default NOWORKLOAD system statistics if no WORKLOAD system statistics have been gathered. It can only be disabled by setting an undocumented parameter or by changing the OPTIMIZER_FEATURES_ENABLE parameter back to 9i compatibility.
You can check the status of your system statistics by running the following query in SQL*Plus:
column sname format a20
column pname format a20
column pval2 format a20
select
sname
, pname
, pval1
, pval2
from
sys.aux_stats$;Can you show us the actual (complete) output you get from "utlxpls.sql"? Use the \ tag to preserve formatting here:
\output
\will show asoutput
Regards,
Randolf
Oracle related stuff blog:
http://oracle-randolf.blogspot.com/
SQLTools++ for Oracle (Open source Oracle GUI for Windows):
http://www.sqltools-plusplus.org:7676/
http://sourceforge.net/projects/sqlt-pp/ -
Not Understanding the filter in Explain Plan - filter(NULL IS NOT NULL)
Hi All,
Request your help in understanding the below scenario. (I am not aware of teh application and table details. Just trying to help my friend)
SQL> conn
Enter user-name: [email protected]
Enter password:
Connected.
SQL> select * from v$version;
BANNER
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi
PL/SQL Release 10.2.0.3.0 - Production
CORE 10.2.0.3.0 Production
TNS for Linux: Version 10.2.0.3.0 - Production
NLSRTL Version 10.2.0.3.0 - Production
--Checking the count in PO_LINES
SQL> select count(*) from po_lines;
COUNT(*)
0
--PO_LINES is a synonym
SQL> select object_type,owner from dba_objects where object_name = 'PO_LINES';
OBJECT_TYPE OWNER
SYNONYM APPS
--The synonym is pointing to PO.PO_LINES_ALL
SQL> select * from user_synonyms where synonym_name = 'PO_LINES';
SYNONYM_NAME TABLE_OWNER TABLE_NAME DB_LINK
PO_LINES PO PO_LINES_ALL
--But when counting PO.PO_LINES_ALL I am getting different result
SQL> select count(*) c from po.po_lines_all;
C
8828
--Explain plan of teh original query is
SQL> explain plan for
2 select
3 * from po_lines;
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
| 0 | SELECT STATEMENT | | 1 | 252 | 0 (0)|
|* 1 | FILTER | | | | |
| 2 | TABLE ACCESS FULL| PO_LINES_ALL | 8796 | 2164K| 106 (4)|
Predicate Information (identified by operation id):
1 - filter(NULL IS NOT NULL)
--Now the object PO.PO_LINES_ALL is TABLE, not an mview.
SQL> select object_type,owner from dba_objects where object_name = 'PO_LINES_ALL';
OBJECT_TYPE OWNER
TABLE POSeek your help in understanding what is happening here.
Thanks in Advance,
jeneeshNext time, prefix with APPS. when you show us the explain plan:
SQL> explain plan for
2 select
3 * from apps.po_lines; -- added the prefix of owner.Just like you prefixed with PO. when you showed us the query on PO_LINES_ALL. It ensures that you are using the synonym which you showed us.
Btw. PO_LINES_ALL, could still be a VIEW given your overview of the situation.
Anyway a filter "NULL IS NOT NULL" is indicative that the optimizer performed something called semantic query optimization (SQO).
SQO is the process of deducing new predicates based upon a) existing predicates in your query (which there is none), b) added predicates to your query (eg. by a VPD policy function), and c) declared constraints on the tables invovled in your query.
A typical example of when a "NOT is NOT NULL" predicate will show up is when for instance in the EMP table there is a declared constraint on EMPNO like this:
check(EMPNO > 0)And your query would hold a predicate that is inconsistent with the constraint, for instance like this:
select *
from EMP
where EMPNO <= 0Oracle will deduce that EMPNO cannot be both greater than zero (constraint) as well as smaller than or equal to zero (your query predicate), and will transform the query into:
select *
from EMP
where EMPNO <= 0
and NULL is NOT NULLThus preventing accessing the EMP table all together, and immediately returning this query with no data found.
Edited by: Toon Koppelaars on Mar 15, 2010 7:17 AM -
Filter(NULL IS NOT NULL) in Explain Plan ??
Hi All,
Can someone please explain what this explain plan statement means? I see a filter(NULL IS NOT NULL) as the first statement - could not figure out why it came up so from googling.
My Query Used:
EXPLAIN PLAN FOR
MERGE INTO summary_bysrccd
USING
(SELECT LAST_DAY(TRUNC(to_timestamp(os.requestdatetime, 'yyyymmddhh24:mi:ss.ff4'))) AS SUMMARY_DATE,
os.acctnum,
ol.sourcecode AS sourcecode,
ol.sourcename AS sourcename,
count(1) cnt_articleview
FROM article_views os , master_sourcecode ol
where os.sourcecode = ol.sourcecode
AND os.acctnum IS NOT NULL
AND ol.sourcecode IS NOT NULL
AND os.requestdatetime IS NOT NULL
AND UPPER(os.success_ind) = 'S'
AND (
('INCR' = 'FULL'
AND (get_date_timestamp(os.requestdatetime) BETWEEN TO_DATE('23-AUG-2011 00:00:00','DD-MON-YYYY HH24:MI:SS') AND TO_DATE('27-AUG-2011 23:59:59','DD-MON-YYYY HH24:MI:SS')
AND os.entry_CreatedDate BETWEEN TO_DATE('22-AUG-2011 00:00:00','DD-MON-YYYY HH24:MI:SS') AND TO_DATE('28-AUG-2011 00:00:00','DD-MON-YYYY HH24:MI:SS')
OR ('INCR' = 'FULL'
AND os.entry_createddate BETWEEN TO_DATE('23-AUG-2011 00:00:00','DD-MON-YYYY HH24:MI:SS') AND TO_DATE('27-AUG-2011 23:59:59','DD-MON-YYYY HH24:MI:SS') )
group by LAST_DAY(TRUNC(to_timestamp(os.requestdatetime, 'yyyymmddhh24:mi:ss.ff4'))),
os.acctnum,ol.sourcecode,ol.sourcename) mrg_query
ON (ods_av_summary_bysrccd.acctnum = mrg_query.acctnum AND
ods_av_summary_bysrccd.summary_date=mrg_query.summary_date AND
ods_av_summary_bysrccd.sourcecode=mrg_query.sourcecode)
WHEN NOT MATCHED THEN
INSERT (SUMMARY_date,ACCTNUM,SOURCECODE,SOURCENAME,CNT_ARTICLEVIEW,ENTRY_LASTUPDATEDDATE)
VALUES(mrg_query.summary_date,mrg_query.acctnum,mrg_query.sourcecode,mrg_query.sourcename,
mrg_query.cnt_articleview,sysdate)
WHEN MATCHED THEN
UPDATE SET ods_av_summary_bysrccd.cnt_articleview=
CASE WHEN NVL('INCR','INCR') = 'FULL' THEN mrg_query.cnt_articleview
ELSE ods_av_summary_bysrccd.cnt_articleview+mrg_query.cnt_articleview
END,
ods_av_summary_bysrccd.entry_lastupdateddate=sysdate;My Explain Plan:
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
Plan hash value: 268591246
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | Pstart| Pstop |
| 0 | MERGE STATEMENT | | 1 | 456 | | 3 (0)| 00:00:01 | | |
| 1 | MERGE | ODS_AV_SUMMARY_BYSRCCD | | | | | | | |
| 2 | VIEW | | | | | | | | |
| 3 | NESTED LOOPS OUTER | | 1 | 417 | | 3 (0)| 00:00:01 | | |
| 4 | VIEW | | 1 | 360 | | 5 (100)| 00:00:01 | | |
| 5 | SORT GROUP BY | | 1 | 73 | 595M| | | | |
PLAN_TABLE_OUTPUT
|* 6 | FILTER | | | | | | | | |
|* 7 | HASH JOIN | | 6975K| 485M| 3944K| 17594 (1)| 00:03:32 | | |
| 8 | TABLE ACCESS FULL | ODS_MASTER_SOURCECODE | 84021 | 2953K| | 273 (1)| 00:00:04 | | |
|* 9 | TABLE ACCESS BY GLOBAL INDEX ROWID| ODS_ARTICLE_VIEWS | 7007K| 247M| | 826 (0)| 00:00:10 | 33 | 33 |
|* 10 | INDEX FULL SCAN | IDX_AV_ACCTNUM | 25M| | | 26 (0)| 00:00:01 | | |
| 11 | TABLE ACCESS BY GLOBAL INDEX ROWID | ODS_AV_SUMMARY_BYSRCCD | 1 | 57 | | 3 (0)| 00:00:01 | ROWID | ROWID |
|* 12 | INDEX UNIQUE SCAN | ODS_AV_SUMMARY_BYSRCCD_PK | 1 | | | 2 (0)| 00:00:01 | | |
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
6 - filter(NULL IS NOT NULL)
7 - access("OS"."SOURCECODE"="OL"."SOURCECODE")
9 - filter("OS"."REQUESTDATETIME" IS NOT NULL AND "OS"."ENTRY_CREATEDDATE">=TO_DATE(' 2011-08-23 00:00:00', 'syyyy-mm-dd
hh24:mi:ss') AND "OS"."ENTRY_CREATEDDATE"<=TO_DATE(' 2011-08-27 23:59:59', 'syyyy-mm-dd hh24:mi:ss') AND UPPER("OS"."SUCCESS_IND")='S')
10 - filter("OS"."ACCTNUM" IS NOT NULL)
12 - access("ODS_AV_SUMMARY_BYSRCCD"."SUMMARY_DATE"(+)=INTERNAL_FUNCTION("MRG_QUERY"."SUMMARY_DATE") AND
"ODS_AV_SUMMARY_BYSRCCD"."ACCTNUM"(+)="MRG_QUERY"."ACCTNUM" AND "ODS_AV_SUMMARY_BYSRCCD"."SOURCECODE"(+)="MRG_QUERY"."SOURCECODE")
Note
PLAN_TABLE_OUTPUT
- dynamic sampling used for this statementHi Toon,
Thanks for the quick resolution. I went back and verified the table's colunm details and it has a NOT NULL constraint.
Regards,
Chaitanya
P.S: Is it ok if I ask you for some help regarding a production issue I have been encountering since 15 days but haev no clear resolution yet about what/why is the reason (the said issue is neither uniform nor regular - its affecting some modules and happening on some days - i shall give the full details if you are willing to have a look) - i shall start a new post or email you directly - yur convenience. -
Explain plan results are different in SQL Developer than SQL Plus
My Environment:
SQL Developer 1.0.0.15.27
Platform where SQL Developer is running: Windows XP 2002 SP2
Oracle Database and Client 9.2.0.7
Optimizer_mode: FIRST_ROWS
I have the following SQL statement:
SELECT a1.comp_id
FROM temp_au_company a0, au_company a1
WHERE :b2 = a0.temp_emp_code
AND a0.comp_id = a1.comp_id
AND a0.sls_terr_code != a1.sls_terr_code
AND a1.last_mdfy_date > :b1
When I run an Explain in SQL Developer I get the following access path (which is the one I really want):
SELECT STATEMENT TABLE ACCESS(BY INDEX ROWID) FEDLINK.AU_COMPANY NESTED LOOPS INDEX(RANGE SCAN)
FEDLINK.UX2_TEMP_AU_COMPANY
INDEX(RANGE SCAN) FEDLINK.PX1_COMPANY
However, when I execute the statement with sql_trace turned on and use tkprof to generate the actual access path, the statement executes as follows (which is WAY more expensive):
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 3.58 6.68 28136 29232 0 0
total 3 3.58 6.69 28136 29232 0 0
Misses in library cache during parse: 1
Optimizer goal: FIRST_ROWS
Parsing user id: 979 (FEDLINK) (recursive depth: 1)
Rows Row Source Operation
0 NESTED LOOPS
0 TABLE ACCESS FULL AU_COMPANY
0 INDEX RANGE SCAN UX2_TEMP_AU_COMPANY (object id 49783)
Notice the FULL access of au_company.
I understand that SQL Developer has nothing to do with why the statement executed the way it did, but why is the Explain in SQL Developer different than the actual execution plan?
Added note....when I run the explain in SQL Plus it is the same as the actual execution. Here is the explain from SQL Plus:
explain plan for SELECT a1.comp_id
FROM temp_au_company a0, au_company a1
WHERE '1' = a0.temp_emp_code
AND a0.comp_id = a1.comp_id
AND a0.sls_terr_code != a1.sls_terr_code
AND a1.last_mdfy_date > '01-MAY-2006';
PLAN_TABLE_OUTPUT
| Id | Operation | Name | Rows | Bytes | Cost |
| 0 | SELECT STATEMENT | | 2 | 76 | 2597 |
| 1 | NESTED LOOPS | | 2 | 76 | 2597 |
| 2 | TABLE ACCESS FULL | AU_COMPANY | 2 | 42 | 2595 |
| 3 | INDEX RANGE SCAN | UX2_TEMP_AU_COMPANY | 1 | 17 | 2
Thanks,
BrendaThe explain is different (full scan of au_company in SQL Plus / index access in SQL Developer) even when I use variables in SQL Plus. Here is the output for SQL Plus using variables instead of literals:
SQL> variable b1 varchar2
SQL> variable b2 char
SQL> explain plan for SELECT a1.comp_id
2 FROM temp_au_company a0, au_company a1
3 WHERE :b2 = a0.temp_emp_code
4 AND a0.comp_id = a1.comp_id
5 AND a0.sls_terr_code != a1.sls_terr_code
6 AND a1.last_mdfy_date > :b1
7 /
Explained.
PLAN_TABLE_OUTPUT
| Id | Operation | Name | Rows | Bytes | Cost |
| 0 | SELECT STATEMENT | | 3184 | 118K| 2995 |
| 1 | HASH JOIN | | 3184 | 118K| 2995 |
| 2 | INDEX RANGE SCAN | UX2_TEMP_AU_COMPANY | 3187 | 54179 | 3 |
| 3 | TABLE ACCESS FULL | AU_COMPANY | 24009 | 492K| 2983 |
Any other ideas? They should be the same.
Brenda
Maybe you are looking for
-
Help regarding regular expression
HI All , Please see the following string String s = "IF ((NOT NUM4 IS ALPHABETIC ) AND NUM3 IS ALPHABETIC-UPPER AND (NUM5 IS GREATER OR EQUAL TO 3) AND (NUM5 IS NOT GREATER THAN 3) AND (NUM3 GREATER THAN 46) AND (NUM5 GREATER THAN NUM3) OR NUM3 LESS
-
I have several dropdown lists in my bookmarks toolbar and would like to access the properties for some of the the items. This used to work fine. However, now, when I go to the list and place the cursor on a particular item, the context menu that is u
-
No Safari, No Mail...
For 2 weeks I have been without any email or internet on my G5 Mac. It just suddenly went off and try as I might I cannot get the connection back up. My IP is BT Broadband and I have spent countless hours on the phone trying to solve this problem and
-
Wie kann ich die mac os lion neu installieren?
Hallo, ich habe die software mac os lion per online gekauft und auf meine mac book installiert. heute habe ich mein Mackbook neue installiert und als versehen meine Backup-Festplatte formatiert. Jetzt möchte das Betriebsystem neue installieren.. Ich
-
The forward/backwardarrow of my firefox browser are not working. I already tried the remedies of resetting toolbars and disabling addons during firefox safemode but problem still occur after I restart firefox. == This happened == Every time Firefox o