Help reading an explain plan
Here is an except from an explain plan.
what does index$_join_002 mean?
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 74 | 133K (1)| 00:31:04 |
|* 1 | FILTER | | | | | |
|* 2 | HASH JOIN RIGHT SEMI | | 26855 | 1940K| 10561 (1)| 00:02:28 |
|* 3 | VIEW | index$_join$_002 | 66364 | 907K| 851 (2)| 00:00:12
I am having trouble forcing a good plan. I have 2 databases with comparable data sets and the indexes are the same. One has a good plan and one a bad plan. When I analyze the tables in the database with the good plan, it changes to the bad plan.
Definiton of good plan: returns in 3 seconds
definition of bad plan: returns in 6 minutes.
Note that as soon as i analyzed the tables, I started getting the bad plan. I am at a loss on how to force the plan to change.
BAD PLAN
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 70 | 62008 (1)| 00:14:29 |
|* 1 | FILTER | | | | | |
|* 2 | HASH JOIN SEMI | | 29528 | 2018K| 1501 (1)| 00:00:22 |
|* 3 | TABLE ACCESS BY INDEX ROWID | EXT_T | 29528 | 1614K| 1344 (0)| 00:00:19 |
| 4 | DOMAIN INDEX | EXT_TEXT_IND | | | 13441 (0)| 00:03:09 |
| 5 | MAT_VIEW ACCESS BY INDEX ROWID | KM_MV | 107K| 1464K| 155 (0)| 00:00:03 |
|* 6 | INDEX RANGE SCAN | KAP_IND | 107K| | 136 (1)| 00:00:02 |good plan. I dont get this when I analyze my tables.
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 74 | 133K (1)| 00:31:04 |
|* 1 | FILTER | | | | | |
|* 2 | HASH JOIN RIGHT SEMI | | 26855 | 1940K| 10561 (1)| 00:02:28 |
|* 3 | VIEW | index$_join$_002 | 66364 | 907K| 851 (2)| 00:00:12 |
|* 4 | HASH JOIN | | | | | |
|* 5 | INDEX RANGE SCAN | KAP_IND | 66364 | 907K| 105 (1)| 00:00:02 |
| 6 | INDEX FAST FULL SCAN | KAP_PK | 66364 | 907K| 742 (1)| 00:00:11 |
|* 7 | TABLE ACCESS BY INDEX ROWID | EXT_T | 26855 | 1573K| 9709 (0)| 00:02:16 |
| 8 | DOMAIN INDEX | EXT_TEXT_IND | | | 9709 (0)| 00:02:16 |Edited by: Guess2 on Jul 1, 2009 9:06 AM
Edited by: Guess2 on Jul 1, 2009 9:07 AM
Edited by: Guess2 on Jul 1, 2009 9:07 AM
Edited by: Guess2 on Jul 1, 2009 9:08 AM
Similar Messages
-
Query Performance and reading an Explain Plan
Hi,
Below I have posted a query that is running slowly for me - upwards of 10 minutes which I would not expect. I have also supplied the explain plan. I'm fairly new to explain plans and not sure what the danger signs are that I should be looking out for.
I have added indexes to these tables, a lot of which are used in the JOIN and so I expected this to be quicker.
Any help or pointers in the right direction would be very much appreciated -
SELECT a.lot_id, a.route, a.route_rev
FROM wlos_owner.tbl_current_lot_status_dim a, wlos_owner.tbl_last_seq_num b, wlos_owner.tbl_hist_metrics_at_op_lkp c
WHERE a.fw_ver = '2'
AND a.route = b.route
AND a.route_rev = b.route_rev
AND a.fw_ver = b.fw_ver
AND a.route = c.route
AND a.route_rev = c.route_rev
AND a.fw_ver = c.fw_ver
AND a.prod = c.prod
AND a.lot_type = c.lot_type
AND c.step_seq_num >= a.step_seq_num
PLAN_TABLE_OUTPUT
Plan hash value: 2447083104
| Id | Operation | Name | Rows | Bytes | Cost
(%CPU)| Time |
PLAN_TABLE_OUTPUT
| 0 | SELECT STATEMENT | | 333 | 33633 | 1347
(8)| 00:00:17 |
|* 1 | HASH JOIN | | 333 | 33633 | 1347
(8)| 00:00:17 |
|* 2 | HASH JOIN | | 561 | 46002 | 1333
(7)| 00:00:17 |
|* 3 | TABLE ACCESS FULL| TBL_CURRENT_LOT_STATUS_DIM | 11782 | 517K| 203
(5)| 00:00:03 |
PLAN_TABLE_OUTPUT
|* 4 | TABLE ACCESS FULL| TBL_HIST_METRICS_AT_OP_LKP | 178K| 6455K| 1120
(7)| 00:00:14 |
|* 5 | TABLE ACCESS FULL | TBL_LAST_SEQ_NUM | 8301 | 154K| 13
(16)| 00:00:01 |
PLAN_TABLE_OUTPUT
Predicate Information (identified by operation id):
1 - access("A"."ROUTE"="B"."ROUTE" AND "A"."ROUTE_REV"="B"."ROUTE_REV" AND
"A"."FW_VER"=TO_NUMBER("B"."FW_VER"))
2 - access("A"."ROUTE"="C"."ROUTE" AND "A"."ROUTE_REV"="C"."ROUTE_REV" AND
"A"."FW_VER"="C"."FW_VER" AND "A"."PROD"="C"."PROD" AND "A"."LOT_T
YPE"="C"."LOT_TYPE")
filter("C"."STEP_SEQ_NUM">="A"."STEP_SEQ_NUM")
3 - filter("A"."FW_VER"=2)
PLAN_TABLE_OUTPUT
4 - filter("C"."FW_VER"=2)
5 - filter(TO_NUMBER("B"."FW_VER")=2)
24 rows selected.Guys thank you for your help.
I changed the type of the offending column and the plan looks a lot better and results seem a lot quicker.
However I have added to my SELECT, quite substantially, and have a new explain plan.
There are two sections in particular that have a high cost and I was wondering if you seen anything inherently wrong or can explain more fully what the PLAN_TABLE_OUTPUT descriptions are telling me - in particular
INDEX FULL SCAN
PLAN_TABLE_OUTPUT
Plan hash value: 3665357134
| Id | Operation | Name | Rows
| Bytes | Cost (%CPU)| Time |
PLAN_TABLE_OUTPUT
| 0 | SELECT STATEMENT | |
4 | 316 | 52 (2)| 00:00:01 |
|* 1 | VIEW | |
4 | 316 | 52 (2)| 00:00:01 |
| 2 | WINDOW SORT | |
4 | 600 | 52 (2)| 00:00:01 |
|* 3 | TABLE ACCESS BY INDEX ROWID | TBL_HIST_METRICS_AT_OP_LKP |
1 | 71 | 1 (0)| 00:00:01 |
PLAN_TABLE_OUTPUT
| 4 | NESTED LOOPS | |
4 | 600 | 51 (0)| 00:00:01 |
| 5 | NESTED LOOPS | | 7
5 | 5925 | 32 (0)| 00:00:01 |
|* 6 | INDEX FULL SCAN | UNIQUE_LAST_SEQ | 8
9 | 2492 | 10 (0)| 00:00:01 |
| 7 | TABLE ACCESS BY INDEX ROWID| TBL_CURRENT_LOT_STATUS_DIM |
PLAN_TABLE_OUTPUT
1 | 51 | 1 (0)| 00:00:01 |
|* 8 | INDEX RANGE SCAN | TBL_CUR_LOT_STATUS_DIM_IDX1 |
1 | | 1 (0)| 00:00:01 |
|* 9 | INDEX RANGE SCAN | TBL_HIST_METRIC_AT_OP_LKP_IDX1 | 2
9 | | 1 (0)| 00:00:01 |
PLAN_TABLE_OUTPUT
Predicate Information (identified by operation id):
1 - filter("SEQ"=1)
3 - filter("C"."FW_VER"=2 AND "A"."PROD"="C"."PROD" AND "A"."LOT_TYPE"="C"."L
OT_TYPE" AND
"C"."STEP_SEQ_NUM">="A"."STEP_SEQ_NUM")
6 - access("B"."FW_VER"=2)
filter("B"."FW_VER"=2)
PLAN_TABLE_OUTPUT
8 - access("A"."ROUTE"="B"."ROUTE" AND "A"."ROUTE_REV"="B"."ROUTE_REV" AND "A
"."FW_VER"=2)
9 - access("A"."ROUTE"="C"."ROUTE" AND "A"."ROUTE_REV"="C"."ROUTE_REV") -
Hi,
I was trying to get an explain plan for below query. (Refer - A)
BILL_DETAIL table have index of ZONECODE,MRNO,AREACODE,WCNO but still it's
showing 'TABLE ACCESS FULL in BILL_DETAIL'
If i select only first 4 column, it is going by index. (REFER - B)
As per my knowledge index will consider only where clause conditions
but here I couldn't understand why this considering select output columns.
First time I am trying sql explain plan statement, Please help me to correct
this query.
REFER - A
EXPLAIN PLAN FOR
SELECT B.ZONECODE ZONECODE, B.MRNO MRNO, B.AREACODE AREACODE, B.WCNO WCNO,
B.BILLNO BILLNO,B.BILLDT BILLDT,B.FROMDT FROMDT,B.TODT TODT,B.TOBEPAID TOBEPAID,
B.PREVUNPAID PREVUNPAID,B.DUEDT DUEDT
FROM BILL_DETAIL B, CONSUMER_MASTER C
WHERE B.ZONECODE = C.ZONECODE
AND B.MRNO = C.MRNO
AND B.AREACODE = C.AREACODE
AND B.WCNO = C.WCNO
AND UPPER(B.ZONECODE)=UPPER('SZ-4')
AND UPPER(B.MRNO)=UPPER('347')
AND UPPER(B.AREACODE)=UPPER('18')
AND UPPER(B.WCNO)=UPPER('30910')
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
| 0 | SELECT STATEMENT | | 1 | 71 | 9 (0)|
| 1 | NESTED LOOPS | | 1 | 71 | 9 (0)|
|* 2 | TABLE ACCESS FULL| BILL_DETAIL | 1 | 52 | 9 (0)|
|* 3 | INDEX UNIQUE SCAN| SYS_C008803 | 1 | 19 | 0 (0)|
Predicate Information (identified by operation id):
2 - filter(UPPER("B"."ZONECODE")='SZ-4' AND UPPER("B"."MRNO")='347'
AND UPPER("B"."AREACODE")='18' AND UPPER("B"."WCNO")='30910')
3 - access("B"."ZONECODE"="C"."ZONECODE" AND "B"."MRNO"="C"."MRNO"
AND "B"."AREACODE"="C"."AREACODE" AND "B"."WCNO"="C"."WCNO")
REFER - B
EXPLAIN PLAN FOR
SELECT B.ZONECODE ZONECODE, B.MRNO MRNO, B.AREACODE AREACODE, B.WCNO WCNO
FROM BILL_DETAIL B, CONSUMER_MASTER C
WHERE B.ZONECODE = C.ZONECODE
AND B.MRNO = C.MRNO
AND B.AREACODE = C.AREACODE
AND B.WCNO = C.WCNO
AND UPPER(B.ZONECODE)=UPPER('SZ-4')
AND UPPER(B.MRNO)=UPPER('347')
AND UPPER(B.AREACODE)=UPPER('18')
AND UPPER(B.WCNO)=UPPER('30910')
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
| 0 | SELECT STATEMENT | | 1 | 34 | 4 (0)|
| 1 | NESTED LOOPS | | 1 | 34 | 4 (0)|
|* 2 | INDEX FAST FULL SCAN| SYS_C008798 | 1 | 15 | 4 (0)|
|* 3 | INDEX UNIQUE SCAN | SYS_C008803 | 1 | 19 | 0 (0)|
Predicate Information (identified by operation id):
2 - filter(UPPER("B"."ZONECODE")='SZ-4' AND UPPER("B"."MRNO")='347'
AND UPPER("B"."AREACODE")='18' AND UPPER("B"."WCNO")='30910')
3 - access("B"."ZONECODE"="C"."ZONECODE" AND "B"."MRNO"="C"."MRNO"
AND "B"."AREACODE"="C"."AREACODE" AND "B"."WCNO"="C"."WCNO")
Note
- 'PLAN_TABLE' is old versionWelcome to the forums!
user13295080 wrote:
I was trying to get an explain plan for below query. (Refer - A)
BILL_DETAIL table have index of ZONECODE,MRNO,AREACODE,WCNO but still it's
showing 'TABLE ACCESS FULL in BILL_DETAIL'
If i select only first 4 column, it is going by index. (REFER - B)
As per my knowledge index will consider only where clause conditions
but here I couldn't understand why this considering select output columns.This is because Oracle is smart enough to know that the entire query can be satisfied by using the index without hitting the table. However, once you add a column that doesn't exist in the index Oracle has decided it is more efficient to use the full table scan.
I also noticed that all the row estimates are 1 in the execution plans. Is this expected? If not, have statistics on the relevant objects been gathered?
Generally speaking, when you have a query tuning question providing information in these threads is extremely helpful:
{message:id=1812597}
{thread:id=863295}
Additionally, when posting query plans, queries, or any code please use \ tags to preserve formatting.
Your code here!\ -
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! -
Help needed in explain plan?
Hi,
Can anyone send me good link to learn explain plan..Hi,
Please check [Tuning SQL Statements Using Explain Plan|http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:231814117467] and [19 Using EXPLAIN PLAN|http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/ex_plan.htm#i19260] (for 10.2, but there is similar information for other versions in the correlated manual), I hope it can help you.
Regards, -
Help me in reading/understanding Explain Plan
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
SELECT SRC2.PGM_MSTR_NBR,
SRC2.PGM_TRK_NBR,
SRC2.CNTL_LOCN,
SRC2.PGM_NAME,
SRC2.PGM_STS,
SRC2.SIS_PGM_START_DATE,
SRC2.SIS_PGM_END_DATE,
SRC2.AWARD_TRGT,
SRC2.AWARD_MAX,
SRC2.COMPLNC_TYPE,
SRC2.CMPNY_VNDR_LOCN,
SRC2.CMPNY_VNDR_NBR,
LKP3.ADDR_NAME,
SRC2.INV_IND,
SRC2.LAST_INV_THRU_DATE,
SRC2.INV_RPT_DAY,
SRC2.INV_RPT_CYCLE,
SRC2.BEG_COLL_DATE,
SRC2.END_COLL_DATE,
SRC2.SLS_CONT_DIST,
SRC2.SLS_CONT_NBR,
SRC2.ORD_INV_START_DATE,
SRC2.ORD_INV_END_DATE,
SRC2.CMPLNC_RPT_IND,
SRC2.PROD_ENTRY_LVL,
SRC2.DIST_ENTRY_LVL,
SRC2.CUST_ENTRY_LVL,
SRC2.VNDR_ENTRY_LVL,
SRC2.VNDR_CONT,
SRC2.SIS_CMPNY_VNDR_NBR
FROM CASADM.SBA_REB_PGM SRC2
INNER JOIN(SELECT PGM_MSTR_NBR,PGM_TRK_NBR,CNTL_LOCN FROM CASADM.ACCR_SIS_PURCH_DTL
UNION SELECT PGM_MSTR_NBR,PGM_TRK_NBR,CNTL_LOCN FROM CASADM.ACCR_SIS_EXCL_DTL)ACCR2
ON (SRC2.PGM_MSTR_NBR=ACCR2.PGM_MSTR_NBR AND SRC2.PGM_TRK_NBR=ACCR2.PGM_TRK_NBR AND SRC2.CNTL_LOCN=ACCR2.CNTL_LOCN)
LEFT OUTER JOIN
CASADM.MT_CMPNY_VNDR LKP3
ON (LKP3.CMPNY_VNDR_NBR=SRC2.CMPNY_VNDR_NBR);
Record Count in each table:
select count(*) from casadm.accr_sis_purch_dtl --375,968
select count(*) from casadm.accr_sis_excl_dtl --1,988,867
select count(*) from casadm.sba_reb_pgm --526,133
select count(*) from casadm.mt_cmpny_vndr --20743
Execution Plan
Plan hash value: 1465316812
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time|
| 0 | SELECT STATEMENT | | 9 | 1908 | | 26988 (2)| 00:06:18 |
| 1 | NESTED LOOPS OUTER | | 9 | 1908 | | 26988 (2)| 00:06:18 |
|* 2 | HASH JOIN | | 9 | 1656 |83M| 26979 (2)| 00:06:18|
| 3 | TABLE ACCESS FULL | SBA_REB_PGM | 536K| 77M| | 2624 (2)| 00:00:37 |
| 4 | VIEW | | 2364K| 74M| | 16424 (2)| 00:03:50 |
| 5 | SORT UNIQUE | | 2364K| 49M|72M| 16424 (86)| 00:03:50|
| 6 | UNION-ALL | | | || | |
| 7 | INDEX FAST FULL SCAN | ACCR_SIS_PURCH_DTL_PK | 375K| 8077K|| 871 (1)| 00:00:13 |
| 8 | TABLE ACCESS FULL | ACCR_SIS_EXCL_DTL | 1988K| 41M|| 5634 (1)| 00:01:19 |
| 9 | TABLE ACCESS BY INDEX ROWID| MT_CMPNY_VNDR | 1 | 28 | | 1 (0)| 00:00:01 |
|* 10 | INDEX UNIQUE SCAN | MT_CMPNY_VNDR_PK | 1 | | | 0 (0)| 00:00:01 |
Predicate Information (identified by operation id):
2 - access("SRC2"."PGM_MSTR_NBR"="ACCR2"."PGM_MSTR_NBR" AND
"SRC2"."PGM_TRK_NBR"="ACCR2"."PGM_TRK_NBR" AND "SRC2"."CNTL_LOCN"=
"ACCR2"."CNTL_LOCN")
10 - access("LKP3"."CMPNY_VNDR_NBR"(+)="SRC2"."CMPNY_VNDR_NBR")
Statistics
102 recursive calls
0 db block gets
34558 consistent gets
23241 physical reads
88 redo size
531258 bytes sent via SQL*Net to client
2760 bytes received via SQL*Net from client
361 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
5392 rows processedWith respect to HASH JOIN it has two operands a TABLE ACCESS FULL and VIEW. Oracle joins these results together based on the following access predicate:
2 - access("SRC2"."PGM_MSTR_NBR"="ACCR2"."PGM_MSTR_NBR" AND
"SRC2"."PGM_TRK_NBR"="ACCR2"."PGM_TRK_NBR" AND "SRC2"."CNTL_LOCN"="ACCR2"."CNTL_LOCN")The VIEW is the result of the union between the CASADM.ACCR_SIS_PURCH_DTL and CASADM.ACCR_SIS_EXCL_DTL where instead of accessing the table CASADM.ACCR_SIS_PURCH_DTL Oracle was able to acquire all the data from the index ACCR_SIS_PURCH_DTL_PK .
The TABLE ACCESS FULL is exactly what says a full table access of SBA_REB_PGM.
The NESTED LOOPS OUTER has two operands like the HASH JOIN. The way this works is that for each result returned by the HASH JOIN operation it accesses the index MT_CMPNY_VNDR_PK and then the table MT_CMPNY_VNDR based on the following access predicate:
10 - access("LKP3"."CMPNY_VNDR_NBR"(+)="SRC2"."CMPNY_VNDR_NBR")It'd probably be worthwhile for you to review the following paper by Christian Antognini Interpreting Execution Plans as well. -
Help needed in EXPLAIN PLAN for a partitioned table
Oracle Version 9i
(Paste execution plan in a spreadsheet to make sense out of it)
I am trying to tune this query -
select * from comm c ,dates d
where
d.active_period = 'Y'
and c.period = d.period;
Operation Object Name Rows Bytes Cost Object Node In/Out PStart PStop
SELECT STATEMENT Optimizer Mode=CHOOSE 5 M 278887
HASH JOIN 5 M 5G 278887
TABLE ACCESS FULL SCHEMA.DATES 24 1 K 8
PARTITION LIST ALL 1 8
TABLE ACCESS FULL SCHEMA.COMM 6 M 5G 277624 1 8
However, I know that the dates table will return only one record. So, if I add another condition to the above query, I get this execution plan. The comm table is huge but it is partitioned on period.
select * from comm c ,dates d
where
d.active_period = 'Y'
and c.period = qd.period
and c.period = 'OCT-07'
Operation Object Name Rows Bytes Cost Object Node In/Out PStart PStop
SELECT STATEMENT Optimizer Mode=CHOOSE 1 8
MERGE JOIN CARTESIAN 1 9 K 8
TABLE ACCESS FULL SCHEMA.DATES 1 69 8
BUFFER SORT 1 9 K
TABLE ACCESS BY LOCAL INDEX ROWID SCHEMA.COMM 1 9 K 7 7
INDEX RANGE SCAN SCHEMA.COMM_NP9 1 7 7
How can I make the query such that the comm table does not have to traverse all of its partitions? The partitioning is based on quarters so it will get its data in one partition only (in the above example - partition no. 7)
Thanks in advance for writing in your replies :)You need to specify period = 'OCT-07', otherwise there is no way the optimizer can know it needs to access only one partition.
Alternatively, partition the DATES table in exactly the same way on "period", and partition-wise joins should kick in, and effectively accessing only the active partition. -
Oracle 11g R2,
Windows 7 OS.
I would like to know, how oracle is using the view in the below explain plan and is it possible to skip using of view in below explain plan(but i don't want to go for NO_INDEX or FULL hints).I purpose fully didn't pasted the time,bytes,rows parameters.Only thing is view is used, and upon this i want clarity
select e.employee_id,e.first_name from employees e;
OPERATION OPTIONS OBJECT_NAME COST
SELECT STATEMENT 3
VIEW index$_join$_00 3
1
HASH JOIN
INDEX FAST FULL SCAN EMP_EMP_ID_PK 1
INDEX FAST FULL SCAN EMP_NAME_IX 1 One more thing i would like to add, this is just sample HR schema(default schema) in oracle.View "EMP_DETAILS_VIEW" is already present in this schema, which selects first_name,last_name etc.. from employee table.
Thanks.
Edited by: 902629 on Dec 15, 2011 10:40 AMExecute alter session set "_INDEX_JOIN_ENABLED"=FALSE; and execute the query.
help reading an explain plan
Thanks -
Hello ALL,
I have the following explain plan, can any body explain the meaning of this explain plan
SELECT * FROM
2 TABLE(DBMS_XPLAN.DISPLAY('PLAN_TABLE','111'));
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost |
| 0 | SELECT STATEMENT | | 401 | 25263 | | 751K|
| 1 | MERGE JOIN SEMI | | 401 | 25263 | | 751K|
| 2 | SORT JOIN | | 17M| 820M| 2108M| 75297 |
| 3 | TABLE ACCESS FULL | TABLE1 | 17M| 820M| | 3520 |
|* 4 | SORT UNIQUE | | 275M| 3412M| 10G| 676K|
| 5 | VIEW | VW_NSO_1 | 275M| 3412M| | 3538 |
|* 6 | HASH JOIN | | 275M| 7874M| | 3538 |
|* 7 | TABLE ACCESS FULL| TABLE2 | 16 | 128 | | 2 |
|* 8 | TABLE ACCESS FULL| TABLE1 | 17M| 360M| | 3520 |
Predicate Information (identified by operation id):
4 - access("TABLE1"."POSITION"="VW_NSO_1"."$nso_col_1")
filter("TABLE1"."POSITION"="VW_NSO_1"."$nso_col_1")
6 - access("TABLE2"."VERSION_NO"="TABLE1"."VERSION_NO")
7 - filter("TABLE2"."STATIC_UPD_FLAG"='N')
8 - filter("TABLE1"."DATETIME_INSERTED">TO_DATE('0004-01-01 00:00:00',
'yyyy-mm-dd hh24:mi:ss'))
Note: cpu costing is off
26 rows selected.
SQL>There is a section in the manual on interpreting the output of explain plan http://download-west.oracle.com/docs/cd/B10501_01/server.920/a96533/ex_plan.htm#16972 Tom Kyte also discusses interpreting the plan http://asktom.oracle.com/pls/ask/f?p=4950:8:::::F4950_P8_DISPLAYID:231814117467#7344298017927 (page down about halfway where he starts his book excerpt).
Rows, bytes, and temp space are the cost-based optimizer's guess about the number of rows, bytes, and temp space that will be touched (or consumed) by the operation. The cost is an internal number that has no significance to you when you're reading an explain plan-- it does have some significance when you are examining an event 10046 trace.
Justin
Distributed Database Consulting, Inc.
http://www.ddbcinc.com/askDDBC -
Hi
I need some help with explain plan...tried some documents but didnt get the clarity...here is the query...
explain plan for
select ename,dname,grade
from emp,dept,salgrade
where emp.deptno=dept.deptno
and emp.sal between salgrade.losal and salgrade.hisal;
and here is the explain plan for this query..
PLAN_TABLE_OUTPUT
| Id | Operation | Name | Rows | Bytes | Cost |
| 0 | SELECT STATEMENT | | | | |
| 1 | NESTED LOOPS | | | | |
| 2 | NESTED LOOPS | | | | |
| 3 | TABLE ACCESS FULL | SALGRADE | | | |
|* 4 | TABLE ACCESS FULL | EMP | | | |
| 5 | TABLE ACCESS BY INDEX ROWID| DEPT | | | |
|* 6 | INDEX UNIQUE SCAN | PK_DEPT | | | |
PLAN_TABLE_OUTPUT
Predicate Information (identified by operation id):
4 - filter("EMP"."SAL"<="SALGRADE"."HISAL" AND "EMP"."SAL">="SALGRADE"
."LOSAL")
6 - access("EMP"."DEPTNO"="DEPT"."DEPTNO")
Note: rule based optimization
21 rows selected.
Execution Plan
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 COLLECTION ITERATOR (PICKLER FETCH) OF 'DISPLAY'
[i suppose it will remove all the spaces....so sorry .... :-( ]
now i have some questions regarding this like...
1. wat does these * mean with 4 and 6
2. how we come to know that which part got executed first and others after that.....as we draw a tree to represent all the steps....
3. wat is this Predicate Information
4. wat info is given at the last titled "Execution Plan"
please help
thanks
SidhuSidhu,
1. wat does these * mean with 4 and 6It means that predicates are applied during this step. You'll see that there is a 4 and a 6 in the predicate informatiion, to specify the actual predicates being applied. The star is to indicate the presence of a predicate.
2. how we come to know that which part got executed
first and others after that.....as we draw a tree to
represent all the steps....This example is taken from an AskTom thread. In this thread he described in great detail how such a tree should be read. I cannot do it better.
3. wat is this Predicate InformationThe filters that are applied to restrict the result set.
4. wat info is given at the last titled "Execution
Plan"You were probably autotracing the 'select * from table(dbms_xplan.display)' itself. So this section is not relevant.
Regards,
Rob. -
Need help understanding Explain Plan from 10046 trace
Below is a query and Explain Plan from a 10046 trace shown with trcanlzr.sql.
In the explain plan I don't understand what's happining at line ID 10 and 11. Specifically, is the result at line 11 rowids from lines 12 & 14? and then what? Are those rowids somehow used in line ID 10?
SELECT cp.cred_process_id, cp.provider_id,
brdg_credentialing.get_appl_specialist(cp.cred_process_id,'R') specialist_name,
brdg_cred_report_pkg.provider_name(cp.cred_process_id) provider_name,
ctc_apptype.description appl_type_desc,
TRUNC (brdg_credentialing.get_appl_received_dt(cp.cred_process_id)) init_received_dt,
brdg_code_util.code_descr(brdg_credentialing.get_appl_status_cd_ctc_id(cp.cred_process_id)) appl_status_desc,
brdg_credentialing.get_appl_prac_specialties(cp.cred_process_id,'Y') primary_specialty,
cwh.city practice_city,
UPPER (cwh.state) practice_state,
TRUNC (ch.event_dt) specialist_assign_dt,
DECODE (ctc_apptype.code,'INITPPO', TRUNC (brdg_credentialing.get_appl_received_dt(cp.cred_process_id)),
'REAPP', TRUNC (brdg_credentialing.get_appl_received_dt(cp.cred_process_id)),
'SPECCRED', TRUNC (brdg_credentialing.get_appl_received_dt(cp.cred_process_id)),
'TRANS', TRUNC (brdg_credentialing.get_appl_received_dt(cp.cred_process_id)),
'RECPPO', p.next_recred_dt,
'RECAPP', p.next_recred_dt, NULL) sort_date,
p.next_recred_dt
FROM brdg_cred_app_open_vw cp,
brdg_cat_type_codes ctc_apptype,
brdg_cred_work_history cwh,
brdg_cred_history ch,
brdg_providers p
WHERE cp.type_cd_ctc_id = ctc_apptype.cat_type_code_id
AND ctc_apptype.category_cd = 'CRED'
AND ctc_apptype.type_cd = 'APPTYPE'
AND cp.cred_process_id = cwh.cred_process_id (+)
AND cwh.primary_practice_flag (+) = 'Y'
AND cp.cred_process_id = ch.cred_process_id
AND ch.cred_history_id = (SELECT MAX(cred_history_id)
FROM brdg_cred_history
WHERE cred_process_id = cp.cred_process_id
AND event_cd_ctc_id = brdg_credentialing.get_event_ctc_id ('SEVENT','SPESTCHG'))
AND cp.provider_id = p.provider_id (+)
and brdg_credentialing.get_appl_specialist_id(cp.cred_process_id) = 5
ORDER BY 3 ASC, 3, 5, 12, 6
Explain Plan Operation
ID PID Card Rows Cost SearchCols / Indexed Cols Predicates
0: 1 36 SELECT STATEMENT
1: 0 1 139 36 SORT ORDER BY
2: 1 139 . FILTER [+]
3: 2 1 311 11 .. NESTED LOOPS OUTER
4: 3 1 311 10 ... NESTED LOOPS OUTER
5: 4 1 311 9 .... NESTED LOOPS
6: 5 1 311 8 ....+ NESTED LOOPS
7: 6 4 16 1 ....+. TABLE ACCESS BY INDEX ROWID CAT_TYPE_CODES
8: 7 4 16 1 ....+.. INDEX RANGE SCAN CAT_TYPE_CODE_UK 2/3 [+] [+]
9: 6 1 311 2 ....+. TABLE ACCESS BY INDEX ROWID CRED_PROCESSES [+]
10: 9 183 61927 1 ....+.. INDEX RANGE SCAN CDPR_CTCD_FK1 1/1 [+] [+]
11: 10 1 3 2 ....+... NESTED LOOPS
12: 11 1 16 1 ....+.... TABLE ACCESS BY INDEX ROWID CAT_TYPE_CODES
13: 12 1 16 1 ....+....+ INDEX UNIQUE SCAN CTCD_PK 1/1 [+] [+]
14: 11 1 3 1 ....+.... INDEX UNIQUE SCAN CAT_TYPE_CODE_UK 3/3 [+] [+]
15: 5 1 11 1 ....+ TABLE ACCESS BY INDEX ROWID CRED_HISTORY [+]
16: 15 1 311 1 ....+. INDEX UNIQUE SCAN CDHT_PK 1/1 [+] [+]
17: 16 1 311 ....+.. SORT AGGREGATE
18: 17 1 526 2 ....+... TABLE ACCESS BY INDEX ROWID CRED_HISTORY [+]
19: 18 23 9950 1 ....+.... INDEX RANGE SCAN CDHT_CDPR_FK 1/1 [+] [+]
20: 4 1 219 1 .... TABLE ACCESS BY INDEX ROWID PROVIDERS
21: 20 1 219 1 ....+ INDEX UNIQUE SCAN PROV_PK 1/1 [+] [+]
22: 3 1 311 1 ... TABLE ACCESS BY INDEX ROWID CRED_WORK_HISTORY [+]
23: 22 3 1057 1 .... INDEX RANGE SCAN CDWH_CDPR_FK 1/1 [+] [+]
24: 2 172 .. INLIST ITERATOR
25: 24 1 172 1 ... INDEX UNIQUE SCAN CAT_TYPE_CODE_UK 3/3 [+] [+]
26: 2 1 0 2 .. TABLE ACCESS BY INDEX ROWID CRED_HISTORY [+]
27: 26 23 2004 1 ... INDEX RANGE SCAN CDHT_CDPR_FK 1/1 [+] [+]
(1) X/Y: Where X is the number of searched columns from index, which has a total of Y columns.
(2) Actual rows returned by operation (average if there were more than 1 execution).
2 - filter( NOT EXISTS (SELECT 0 FROM "PPO"."CAT_TYPE_CODES" "BRDG_CAT_TYPE_CODES" WHERE
"CODE"="BRDG_CODE_UTIL"."ID_CODE"("BRDG_CREDENTIALING"."GET_APPL_STATUS_CD_CTC_ID"(:B1)) AND
("TYPE_CD"='APPROVAL' OR "TYPE_CD"='DENIED' OR "TYPE_CD"='INACTIVE' OR "TYPE_CD"='TERMED') AND
"CATEGORY_CD"='APPSTAT') AND NOT EXISTS (SELECT 0 FROM "PPO"."CRED_HISTORY" "BRDG_CRED_HISTORY"
WHERE "CRED_PROCESS_ID"=:B2 AND "EVENT_CD_CTC_ID"="BRDG_CODE_UTIL"."GET_ID"('CRED','SEVENT','MSODC
8 - access("CTC_APPTYPE"."CATEGORY_CD"='CRED' AND "CTC_APPTYPE"."TYPE_CD"='APPTYPE')
9 - filter("BRDG_CREDENTIALING"."GET_APPL_SPECIALIST_ID"("CP"."CRED_PROCESS_ID")=5 AND
("CP"."INS_DT">=TO_DATE(' 2007-12-20 17:00:00', 'syyyy-mm-dd hh24:mi:ss') OR
"CP"."TYPE_CD_CTC_ID"<>"BRDG_CODE_UTIL"."GET_ID"('CRED','APPTYPE','RECPPO')))
10 - access("CP"."TYPE_CD_CTC_ID"="CTC_APPTYPE"."CAT_TYPE_CODE_ID")
filter( NOT EXISTS (SELECT 0 FROM "PPO"."CAT_TYPE_CODES"
"CTC_APPTYPE","PPO"."CAT_TYPE_CODES" "CTC_TYPE" WHERE "CTC_TYPE"."CAT_TYPE_CODE_ID"=:B1 AND
"CTC_TYPE"."CODE"="CTC_APPTYPE"."CODE" AND "CTC_APPTYPE"."TYPE_CD"='APPSENT' AND
"CTC_APPTYPE"."CATEGORY_CD"='APPTYPE'))
13 - access("CTC_TYPE"."CAT_TYPE_CODE_ID"=:B1)
14 - access("CTC_APPTYPE"."CATEGORY_CD"='APPTYPE' AND "CTC_APPTYPE"."TYPE_CD"='APPSENT' AND
"CTC_TYPE"."CODE"="CTC_APPTYPE"."CODE")
15 - filter("CP"."CRED_PROCESS_ID"="CH"."CRED_PROCESS_ID")
16 - access("CH"."CRED_HISTORY_ID"= (SELECT MAX("CRED_HISTORY_ID") FROM "PPO"."CRED_HISTORY"
"BRDG_CRED_HISTORY" WHERE "CRED_PROCESS_ID"=:B1 AND
"EVENT_CD_CTC_ID"="BRDG_CREDENTIALING"."GET_EVENT_CTC_ID"('SEVENT','SPESTCHG')))
18 - filter("EVENT_CD_CTC_ID"="BRDG_CREDENTIALING"."GET_EVENT_CTC_ID"('SEVENT','SPESTCHG'))
19 - access("CRED_PROCESS_ID"=:B1)
21 - access("CP"."PROVIDER_ID"="P"."PROVIDER_ID"(+))
22 - filter("CWH"."PRIMARY_PRACTICE_FLAG"(+)='Y')
23 - access("CP"."CRED_PROCESS_ID"="CWH"."CRED_PROCESS_ID"(+))
25 - access("CATEGORY_CD"='APPSTAT' AND ("TYPE_CD"='APPROVAL' OR "TYPE_CD"='DENIED' OR
"TYPE_CD"='INACTIVE' OR "TYPE_CD"='TERMED') AND "CODE"="BRDG_CODE_UTIL"."ID_CODE"("BRDG_CREDENTIAL
ING"."GET_APPL_STATUS_CD_CTC_ID"(:B1)))
26 - filter("EVENT_CD_CTC_ID"="BRDG_CODE_UTIL"."GET_ID"('CRED','SEVENT','MSODC'))
27 - access("CRED_PROCESS_ID"=:B1)Welcome to the forums!
user11987210 wrote:
In the explain plan I don't understand what's happining at line ID 10 and 11. Specifically, is the result at line 11 rowids from lines 12 & 14? and then what? Are those rowids somehow used in line ID 10?
9: 6 1 311 2 ....+. TABLE ACCESS BY INDEX ROWID CRED_PROCESSES [+]
10: 9 183 61927 1 ....+.. INDEX RANGE SCAN CDPR_CTCD_FK1 1/1 [+] [+]
11: 10 1 3 2 ....+... NESTED LOOPS
12: 11 1 16 1 ....+.... TABLE ACCESS BY INDEX ROWID CAT_TYPE_CODES
13: 12 1 16 1 ....+....+ INDEX UNIQUE SCAN CTCD_PK 1/1 [+] [+]
14: 11 1 3 1 ....+.... INDEX UNIQUE SCAN CAT_TYPE_CODE_UK 3/3 [+] [+] The NESTED LOOPS operation (ID #11) has two children, ID #12 sometimes called the driving source, and ID #14 the inner loop. ID #14 is executed once for each row returned by ID #12. The results of ID #11 are then fed to ID #10 which performs an INDEX RANGE SCAN.
Hope this helps! -
Please help to understand 10g explain plan
Hello
I am trying to optimize one query. I have taken explain plan of this query in 9i and 10g database both.
Explain plan for index scan is different in 9i and 10g. In 9i inedex was scaned with INDEX RANGE SCAN NON-UNIQUE and in 10g index is scanned with
INDEX RANGE SCAN.
Can anybody explain the difference of scanning an index in 9i and 10g? Cost in 9i was 74 and now in 10g it is 1134.
Thanks in advanceWell, if you tables structures and indexes are the same in both databases then that's unlikely to be an issue, however you need to check other factors such as whether statistics have been gathered for the data recently.
For helpful info on optimising queries and what to look out for read the following thread...
[When your query takes too long|http://forums.oracle.com/forums/thread.jspa?messageID=1812597#1812597] -
[8i] Can someone help me on using explain plan, tkprof, etc.?
I am trying to follow the instructions at When your query takes too long ...
I am trying to figure out why a simple query takes so long.
The query is:
SELECT COUNT(*) AS tot_rows FROM my_table;It takes a good 5 minutes or so to run (best case), and the result is around 22 million (total rows).
My generic username does not (evidently) allow access to PLAN_TABLE, so I had to log on as SYSTEM to run explain plan. In SQL*Plus, I typed in:
explain plan for (SELECT COUNT(*) AS tot_rows FROM my_table);and the response was "Explained."
Isn't this supposed to give me some sort of output, or am I missing something?
Then, the next step in the post I linked is to use tkprof. I see that it says it will output a file to a path specified in a parameter. The only problem is, I don't have access to the db's server. I am working remotely, and do not have any way to remotely (or directly) access the db server. Is there any way to have the file output to my local machine, or am I just S.O.L.?SomeoneElse used "create table as" (CTAS), wich automatically gathers the stats. You can see the differende before and after stats clearly in this example.
This is the script:
drop table ttemp;
create table ttemp (object_id number not null, owner varchar2(30), object_name varchar2(200));
alter table ttemp add constraint ttemp_pk primary key (object_id);
insert into ttemp
select object_id, owner, object_name
from dba_objects
where object_id is not null;
set autotrace on
select count(*) from ttemp;
exec dbms_stats.gather_table_stats('PROD','TTEMP');
select count(*) from ttemp;And the result:
Table dropped.
Table created.
Table altered.
46888 rows created.
COUNT(*)
46888
1 row selected.
Execution Plan
SELECT STATEMENT Optimizer Mode=CHOOSE
1 SORT AGGREGATE
2 1 TABLE ACCESS FULL PROD.TTEMP
Statistics
1 recursive calls
1 db block gets
252 consistent gets
0 physical reads
120 redo size
0 PX remote messages sent
0 PX remote messages recv'd
0 buffer is pinned count
0 workarea memory allocated
4 workarea executions - optimal
1 rows processed
PL/SQL procedure successfully completed.
COUNT(*)
46888
1 row selected.
Execution Plan
SELECT STATEMENT Optimizer Mode=CHOOSE (Cost=4 Card=1)
1 SORT AGGREGATE (Card=1)
2 1 INDEX FAST FULL SCAN PROD.TTEMP_PK (Cost=4 Card=46 K)
Statistics
1 recursive calls
2 db block gets
328 consistent gets
0 physical reads
8856 redo size
0 PX remote messages sent
0 PX remote messages recv'd
0 buffer is pinned count
0 workarea memory allocated
4 workarea executions - optimal
1 rows processed -
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 -
I am running the following query against my database
SELECT p.ID
FROM rap_counterparties cou,
rap_presentation_cou_ratings pcr,
rap_presentation_states sta,
rap_app_user_profiles aup,
rap_presentations p
WHERE cou.unt_id = aup.unt_id
AND aup.aur_id = 7529
AND pcr.cou_id = cou.ID
AND sta.cur_present_state_instance_flg = 'Y'
AND sta.state_type_id = pcr.pst_state_type_id
AND sta.pre_id = pcr.pst_pre_id
AND sta.state_type_id IN (326, 322, 323, 324, 325)
AND cou.unt_id = p.unt_id
AND p.ID = sta.pre_id
AND ( p.private_flg != 'Y'
OR (p.private_flg = 'Y' AND p.created_by_user_id = 10000083)
Explain plan of the query is
PLAN_TABLE_OUTPUT
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
| 0 | SELECT STATEMENT | | 8 | 456 | 3936 (16)|
|* 1 | TABLE ACCESS BY INDEX ROWID | RAP_PRESENTATIONS | 1 | 15 | 2 (50)|
| 2 | NESTED LOOPS | | 8 | 456 | 3936 (16)|
|* 3 | HASH JOIN | | 1745 | 73290 | 2145 (27)|
|* 4 | HASH JOIN | | 14257 | 431K| 1299 (25)|
|* 5 | HASH JOIN | | 5173 | 87941 | 583 (16)|
| 6 | TABLE ACCESS BY INDEX ROWID| RAP_APP_USER_PROFILES | 18 | 144 | 3 (34)|
|* 7 | INDEX RANGE SCAN | RAP_AUP_IX_01 | 18 | | 2 (50)|
| 8 | TABLE ACCESS FULL | RAP_COUNTERPARTIES | 118K| 1042K| 560 (13)|
|* 9 | INDEX FAST FULL SCAN | RAP_PCR_PK | 326K| 4467K| 659 (25)|
|* 10 | INDEX FAST FULL SCAN | RAP_PST_IX_02 | 120K| 1291K| 821 (29)|
|* 11 | INDEX RANGE SCAN | RAP_PRE_PK | 1 | | |
Predicate Information (identified by operation id):
1 - filter(("P"."PRIVATE_FLG"<>'Y' OR "P"."CREATED_BY_USER_ID"=10000083 AND
"P"."PRIVATE_FLG"='Y') AND "COU"."UNT_ID"="P"."UNT_ID")
3 - access("STA"."STATE_TYPE_ID"="PCR"."PST_STATE_TYPE_ID" AND
"STA"."PRE_ID"="PCR"."PST_PRE_ID")
4 - access("PCR"."COU_ID"="COU"."ID")
5 - access("COU"."UNT_ID"="AUP"."UNT_ID")
7 - access("AUP"."AUR_ID"=7529)
9 - filter("PCR"."PST_STATE_TYPE_ID"=322 OR "PCR"."PST_STATE_TYPE_ID"=323 OR
"PCR"."PST_STATE_TYPE_ID"=324 OR "PCR"."PST_STATE_TYPE_ID"=325 OR "PCR"."PST_STATE_TYPE_ID"=326)
10 - filter("STA"."CUR_PRESENT_STATE_INSTANCE_FLG"='Y' AND ("STA"."STATE_TYPE_ID"=322 OR
"STA"."STATE_TYPE_ID"=323 OR "STA"."STATE_TYPE_ID"=324 OR "STA"."STATE_TYPE_ID"=325 OR
"STA"."STATE_TYPE_ID"=326))
11 - access("P"."ID"="STA"."PRE_ID")
Table Row count
rap_app_user_profiles : 30639
rap_counterparties : 118583
rap_presentation_cou_ratings -- 652781
rap_presentation_states -- 982413
rap_presentations -- 246145
Questions
1. Why is the index not being used on the table rap_counterparties. If I force a hint then the index is being used
2. Is there a way I can have an index range scan as opposed to the index fast full scan.
3. This query runs in 3s. Is there anything else I can do to tune this query?
4. In predicate 9 and 10 the two tables have fast full scan. If the filter of unit generates only a few records why can't those few records be joined with these tables. Why the whole tables are first being scanned and then joined
Appreciate your responseThanks for the suggestions.
So I tried using the FIRST_ROW HINT and i am getting the nested loops join and it runs fast in 250ms.
SELECT /*+FIRST_ROWS*/
p.ID ID
FROM rap_presentations p,
rap_counterparties cou,
rap_presentation_states sta,
rap_presentation_cou_ratings pcr
WHERE cou.unt_id IN (
SELECT prof.unt_id
FROM rap_application_users u, rap_app_user_profiles prof
WHERE u.ID = prof.aur_id AND u.ID = 7529
AND prof.aro_id NOT IN (8))
AND cou.unt_id = p.unt_id
AND p.ID = sta.pre_id
AND sta.cur_present_state_instance_flg = 'Y'
AND sta.state_type_id = pcr.pst_state_type_id
AND sta.pre_id = pcr.pst_pre_id
AND pcr.cou_id = cou.ID
AND ( p.private_flg != 'Y'
OR (p.private_flg = 'Y' AND p.created_by_user_id = 7529)
AND sta.state_type_id IN (326, 322, 323, 324, 325)
Explain plan:
PLAN_TABLE_OUTPUT
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
| 0 | SELECT STATEMENT | | 7 | 434 | 43334 (2)|
|* 1 | TABLE ACCESS BY INDEX ROWID | RAP_PRESENTATIONS | 1 | 15 | 2 (50)|
| 2 | NESTED LOOPS | | 7 | 434 | 43334 (2)|
| 3 | NESTED LOOPS | | 1593 | 74871 | 41699 (2)|
| 4 | NESTED LOOPS | | 13016 | 457K| 15196 (2)|
| 5 | NESTED LOOPS | | 4723 | 101K| 798 (2)|
| 6 | VIEW | VW_NSO_1 | 16 | 208 | |
| 7 | SORT UNIQUE | | 16 | 256 | |
| 8 | NESTED LOOPS | | 16 | 256 | 4 (25)|
|* 9 | INDEX UNIQUE SCAN | RAP_AUR_PK | 1 | 5 | 2 (50)|
|* 10 | TABLE ACCESS BY INDEX ROWID| RAP_APP_USER_PROFILES | 16 | 176 | 3 (34)|
|* 11 | INDEX RANGE SCAN | RAP_AUP_IX_01 | 18 | | 2 (50)|
| 12 | TABLE ACCESS BY INDEX ROWID | RAP_COUNTERPARTIES | 295 | 2655 | 50 (2)|
|* 13 | INDEX RANGE SCAN | RAP_COU_IX_02 | 95 | | 2 (50)|
|* 14 | TABLE ACCESS BY INDEX ROWID | RAP_PRESENTATION_COU_RATINGS | 3 | 42 | 4 (25)|
|* 15 | INDEX RANGE SCAN | RAP_PCR_IX_03 | 10 | | 3 (34)|
|* 16 | INDEX RANGE SCAN | RAP_PST_IX_02 | 1 | 11 | 3 (34)|
|* 17 | INDEX RANGE SCAN | RAP_PRE_PK | 1 | | |
Predicate Information (identified by operation id):
1 - filter(("P"."PRIVATE_FLG"<>'Y' OR "P"."PRIVATE_FLG"='Y' AND "P"."CREATED_BY_USER_ID"=7529) AND
"COU"."UNT_ID"="P"."UNT_ID")
9 - access("U"."ID"=7529)
10 - filter("PROF"."ARO_ID"<>8)
11 - access("PROF"."AUR_ID"=7529)
13 - access("COU"."UNT_ID"="VW_NSO_1"."$nso_col_1")
14 - filter("PCR"."PST_STATE_TYPE_ID"=322 OR "PCR"."PST_STATE_TYPE_ID"=323 OR
"PCR"."PST_STATE_TYPE_ID"=324 OR "PCR"."PST_STATE_TYPE_ID"=325 OR "PCR"."PST_STATE_TYPE_ID"=326)
15 - access("PCR"."COU_ID"="COU"."ID")
16 - access("STA"."PRE_ID"="PCR"."PST_PRE_ID" AND "STA"."STATE_TYPE_ID"="PCR"."PST_STATE_TYPE_ID" AND
"STA"."CUR_PRESENT_STATE_INSTANCE_FLG"='Y')
filter("STA"."STATE_TYPE_ID"=322 OR "STA"."STATE_TYPE_ID"=323 OR "STA"."STATE_TYPE_ID"=324 OR
"STA"."STATE_TYPE_ID"=325 OR "STA"."STATE_TYPE_ID"=326)
17 - access("P"."ID"="STA"."PRE_ID")
But my query that runs to get the data has a union with another query and with the change it looks like below
SELECT /*+FIRST_ROWS*/
p.ID ID
FROM rap_presentations p,
rap_counterparties cou,
rap_presentation_states sta,
rap_presentation_cou_ratings pcr
WHERE cou.unt_id IN (
SELECT prof.unt_id
FROM rap_application_users u, rap_app_user_profiles prof
WHERE u.ID = prof.aur_id AND u.ID = 7529
AND prof.aro_id NOT IN (8))
AND cou.unt_id = p.unt_id
AND p.ID = sta.pre_id
AND sta.cur_present_state_instance_flg = 'Y'
AND sta.state_type_id = pcr.pst_state_type_id
AND sta.pre_id = pcr.pst_pre_id
AND pcr.cou_id = cou.ID
AND ( p.private_flg != 'Y'
OR (p.private_flg = 'Y' AND p.created_by_user_id = 7529)
AND sta.state_type_id IN (326, 322, 323, 324, 325)
UNION
SELECT /*+index(pfs)*/
p.ID ID
FROM rap_presentations p,
rap_presentation_states sta,
rap_facilities f,
rap_presentation_fac_states pfs
WHERE f.unt_id IN (
SELECT prof.unt_id
FROM rap_application_users u, rap_app_user_profiles prof
WHERE u.ID = prof.aur_id AND u.ID = 7529
AND prof.aro_id NOT IN (8))
AND f.unt_id = p.unt_id
AND p.ID = sta.pre_id
AND sta.cur_present_state_instance_flg = 'Y'
AND sta.state_type_id = pfs.pst_state_type_id
AND sta.pre_id = pfs.pst_pre_id
AND pfs.fac_id = f.ID
AND pfs.fac_num = f.num
AND f.current_facility_instance_flg = 'Y'
AND ( p.private_flg != 'Y'
OR (p.private_flg = 'Y' AND p.created_by_user_id = 7529)
AND sta.state_type_id IN (326, 322, 323, 324, 325)
Explain plan :
PLAN_TABLE_OUTPUT
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
| 0 | SELECT STATEMENT | | 8 | 534 | 14931 (80)|
| 1 | SORT UNIQUE | | 8 | 534 | 14931 (80)|
| 2 | UNION-ALL | | | | |
|* 3 | TABLE ACCESS BY INDEX ROWID | RAP_PRESENTATIONS | 1 | 15 | 2 (50)|
| 4 | NESTED LOOPS | | 7 | 455 | 3728 (17)|
|* 5 | HASH JOIN | | 1542 | 77100 | 2145 (27)|
|* 6 | HASH JOIN | | 12598 | 479K| 1300 (24)|
|* 7 | HASH JOIN | | 4571 | 111K| 584 (16)|
|* 8 | TABLE ACCESS BY INDEX ROWID| RAP_APP_USER_PROFILES | 16 | 176 | 3 (34)|
|* 9 | INDEX RANGE SCAN | RAP_AUP_IX_01 | 18 | | 2 (50)|
| 10 | NESTED LOOPS | | 118K| 1621K| 561 (13)|
|* 11 | INDEX UNIQUE SCAN | RAP_AUR_PK | 1 | 5 | 2 (50)|
| 12 | TABLE ACCESS FULL | RAP_COUNTERPARTIES | 118K| 1042K| 560 (13)|
|* 13 | INDEX FAST FULL SCAN | RAP_PCR_PK | 326K| 4467K| 659 (25)|
|* 14 | INDEX FAST FULL SCAN | RAP_PST_IX_02 | 120K| 1291K| 821 (29)|
|* 15 | INDEX RANGE SCAN | RAP_PRE_PK | 1 | | |
| 16 | NESTED LOOPS | | 1 | 79 | 11201 (2)|
| 17 | NESTED LOOPS | | 75 | 4800 | 11124 (2)|
| 18 | NESTED LOOPS | | 617 | 32701 | 9867 (2)|
| 19 | NESTED LOOPS | | 2104 | 69432 | 5606 (2)|
| 20 | NESTED LOOPS | | 16 | 256 | 4 (25)|
|* 21 | INDEX UNIQUE SCAN | RAP_AUR_PK | 1 | 5 | 2 (50)|
|* 22 | TABLE ACCESS BY INDEX ROWID| RAP_APP_USER_PROFILES | 16 | 176 | 3 (34)|
|* 23 | INDEX RANGE SCAN | RAP_AUP_IX_01 | 18 | | 2 (50)|
|* 24 | TABLE ACCESS BY INDEX ROWID | RAP_FACILITIES | 135 | 2295 | 351 (2)|
|* 25 | INDEX RANGE SCAN | RAP_FAC_IX_02 | 1608 | | 5 (20)|
|* 26 | INDEX RANGE SCAN | RAP_PFR_PK | 1 | 20 | 3 (34)|
|* 27 | INDEX RANGE SCAN | RAP_PST_IX_02 | 1 | 11 | 3 (34)|
|* 28 | TABLE ACCESS BY INDEX ROWID | RAP_PRESENTATIONS | 1 | 15 | 2 (50)|
|* 29 | INDEX UNIQUE SCAN | RAP_PRE_PK | 1 | | |
Predicate Information (identified by operation id):
3 - filter(("P"."PRIVATE_FLG"<>'Y' OR "P"."PRIVATE_FLG"='Y' AND "P"."CREATED_BY_USER_ID"=7529)
AND "COU"."UNT_ID"="P"."UNT_ID")
5 - access("STA"."STATE_TYPE_ID"="PCR"."PST_STATE_TYPE_ID" AND
"STA"."PRE_ID"="PCR"."PST_PRE_ID")
6 - access("PCR"."COU_ID"="COU"."ID")
7 - access("COU"."UNT_ID"="PROF"."UNT_ID")
8 - filter("PROF"."ARO_ID"<>8)
9 - access("PROF"."AUR_ID"=7529)
11 - access("U"."ID"=7529)
13 - filter("PCR"."PST_STATE_TYPE_ID"=322 OR "PCR"."PST_STATE_TYPE_ID"=323 OR
"PCR"."PST_STATE_TYPE_ID"=324 OR "PCR"."PST_STATE_TYPE_ID"=325 OR "PCR"."PST_STATE_TYPE_ID"=326)
14 - filter("STA"."CUR_PRESENT_STATE_INSTANCE_FLG"='Y' AND ("STA"."STATE_TYPE_ID"=322 OR
"STA"."STATE_TYPE_ID"=323 OR "STA"."STATE_TYPE_ID"=324 OR "STA"."STATE_TYPE_ID"=325 OR
"STA"."STATE_TYPE_ID"=326))
15 - access("P"."ID"="STA"."PRE_ID")
21 - access("U"."ID"=7529)
22 - filter("PROF"."ARO_ID"<>8)
23 - access("PROF"."AUR_ID"=7529)
24 - filter("F"."CURRENT_FACILITY_INSTANCE_FLG"='Y')
25 - access("F"."UNT_ID"="PROF"."UNT_ID")
26 - access("PFS"."FAC_ID"="F"."ID" AND "PFS"."FAC_NUM"="F"."NUM")
filter("PFS"."PST_STATE_TYPE_ID"=322 OR "PFS"."PST_STATE_TYPE_ID"=323 OR
"PFS"."PST_STATE_TYPE_ID"=324 OR "PFS"."PST_STATE_TYPE_ID"=325 OR "PFS"."PST_STATE_TYPE_ID"=326)
27 - access("STA"."PRE_ID"="PFS"."PST_PRE_ID" AND
"STA"."STATE_TYPE_ID"="PFS"."PST_STATE_TYPE_ID" AND "STA"."CUR_PRESENT_STATE_INSTANCE_FLG"='Y')
filter("STA"."STATE_TYPE_ID"=322 OR "STA"."STATE_TYPE_ID"=323 OR "STA"."STATE_TYPE_ID"=324
OR "STA"."STATE_TYPE_ID"=325 OR "STA"."STATE_TYPE_ID"=326)
28 - filter(("P"."PRIVATE_FLG"<>'Y' OR "P"."PRIVATE_FLG"='Y' AND "P"."CREATED_BY_USER_ID"=7529)
AND "F"."UNT_ID"="P"."UNT_ID")
29 - access("P"."ID"="STA"."PRE_ID")
Question:
1. When I put the query with the FIRST_ROWS hint in a union with another query, the explain plan reverts back to the older explain plan. how can I avoid it when running by iteslf it runs really quick?
2. Why is the cost with nested loops more higher? Is it because of statistics?
2. Does the database parameter db_multiblock_read_count have any affect on the fast full scan?
3. I gather statistics using the followin method
begin
dbms_stats.gather_schema_stats(
ownname => 'RAP_OWNER',
estimate_percent => dbms_stats.auto_sample_size,
method_opt => 'for all columns size auto',
degree => 7
end;
Sometimes I also use the following method
BEGIN
dbms_stats.gather_schema_stats( ownname=>'RAP_OWNER',
METHOD_OPT=>'FOR ALL INDEXED COLUMNS SIZE SKEWONLY',
CASCADE=>TRUE, ESTIMATE_PERCENT=>100);
END;
Which one is good or should I use both?
Appreciate your input.
Maybe you are looking for
-
IPhoto '11 location pin not working
I just geotagged a bunch of photos in iPhoto 9.2.1 by adding a new location or moving the pin for existing locations in the small locations map in the Information pane of a picture / selection of pictures. After reviewing my changes I noticed that no
-
Report symulating KE30.
Hello all. I have the fallowing problem: Unfortunately for us, we have to archive our database and with it, CE10100 table used for COPA reporting. We also archive VBRP / VBRK tables so we are not going to have information older than 3 months in the s
-
Monitor Does Not Shut Down In 15 Minutes
Under power options the monitor is set to turn off on 15 minutes. updated my Shockwave Flash to 10.0 r42 when a flash video is played in any of of my browser and the browser is shut down the monitor does not shut down in 15 minutes. the computer has
-
I want to buy a new ipad that will be mainly used in south america where at&t and verizon do not offer services. Can the 3G option be used with a local carrier?
-
Re: On Demand still not working
I've been getting error cmod 54004 and a tech came out and said signal was fine that maintenence needed to come and look at levels in the area that was on the 5th it's now the 7th and no one has come. The issue has been going on for over two weeks no