Avoid Full table scan
Hi,
My Query generation needs to be fine tuned. There are several queries generated that force full table scans of large tables. My question over here is whether functions and decodes need to be removed so that the queries take full advantage of the indexes on the table? I have used decode, Sum, case functions. So does it forces a full table scan of item price table (> 200 million records) as many times I have used these functions?
How can I optimized it in more better way?
How to see execution plan? Is it like explain plan you are saying? Can you please brief me on same.
My query is
Select S_ACCT_INFO.CUST_ACCT_NAM as CUST_ACCT_NAM,
S_SLS_CRMEM_ITEM.CUST_ACCT_ID as CUST_ACCT_ID,
S_SLS_CRMEM_ITEM.CUST_CNTRC_ID as CUST_CNTRC_ID,
S_MCK_ITEM.GNRC_ID as GNRC_ID,
S_MCK_ITEM.GNRC_NAM as GNRC_NAM,
S_MCK_ITEM.SELL_DSCR_TXT as SELL_DSCR_TXT,
S_MCK_ITEM.ITEM_STAT_CD_DSPSTN as ITEM_STAT_CD_DSPSTN,
S_MCK_ITEM.RETL_LBL_CNT as RETL_LBL_CNT,
S_MCK_ITEM.LBL_NAM as LBL_NAM,
S_MCK_ITEM.MFG_SIZ_QTY as MFG_SIZ_QTY,
S_SLS_CRMEM_ITEM.EM_ITEM_NUM as EM_ITEM_NUM,
S_MCK_ITEM.NDC_NUM as NDC_NUM,
S_MCK_ITEM.SPLR_ITEM_SEQ_NUM as SPLR_ITEM_SEQ_NUM,
S_MCK_ITEM.SPLR_ACCT_NAM as SPLR_ACCT_NAM,
S_MCK_ITEM.SPLR_ACCT_ID as SPLR_ACCT_ID,
S_MCK_ITEM.UPC_NUM as UPC_NUM,
S_IW_CNTRC_LEAD.CNTRC_LEAD_NAM as CNTRC_LEAD_NAM,
DECODE(S_SLS_CRMEM_ITEM.CNTRC_LEAD_TP_ID, NULL, 'N', 'Y') CNTRC_IND_HIST,
S_SLS_CRMEM_ITEM.CNTRC_LEAD_TP_ID as CNTRC_LEAD_TP_ID,
S_SLS_CRMEM_ITEM.SLS_DOC_NUM as SLS_DOC_NUM,
SUM(S_SLS_CRMEM_ITEM.SLS_AMT) INV_EXT_PRC_3,
S_SLS_CRMEM_ITEM.SLS_PROC_WRK_DT as SLS_PROC_WRK_DT,
CASE
WHEN S_SLS_CRMEM_ITEM.GRS_SLS_QTY <> 0 THEN
ROUND(S_SLS_CRMEM_ITEM.GRS_SLS_AMT / S_SLS_CRMEM_ITEM.GRS_SLS_QTY,
2)
ELSE
0
END INV_PRC_PKG_2,
SUM(S_SLS_CRMEM_ITEM.SLS_QTY) NET_QTY_3,
S_SLS_CRMEM_ITEM.CUST_PO_NUM as CUST_PO_NUM,
CASE
WHEN S_SLS_CRMEM_ITEM.CUST_OMIT_IND IN
('L', 'U', 'R', 'F', 'A', 'X') THEN
SUM(S_SLS_CRMEM_ITEM.ORDR_QTY - S_SLS_CRMEM_ITEM.GRS_SLS_QTY)
ELSE
0
END QTY_OMTD_MUS_1,
S_ACCT_INFO.NATL_SUB_GRP_CD as NATL_SUB_GRP_CD,
S_ACCT_INFO.CUST_STOR_NUM as CUST_STOR_NUM,
S_MCK_ITEM.PKG_SIZ as PKG_SIZ,
SUM(S_SLS_CRMEM_ITEM.GRS_SLS_QTY) INV_QTY_1,
SUM(S_SLS_CRMEM_ITEM.ORDR_QTY) ORDR_QTY_2,
SUM(S_SLS_CRMEM_ITEM.ORDR_QTY - S_SLS_CRMEM_ITEM.GRS_SLS_QTY) QTY_OMTD_1,
SUM(S_SLS_CRMEM_ITEM.GRS_RTN_QTY) RTRN_QTY_1
from S_SLS_CRMEM_ITEM
LEFT OUTER JOIN S_MCK_ACCT_ITEM_PRC ON (S_SLS_CRMEM_ITEM.CUST_ACCT_ID =
S_MCK_ACCT_ITEM_PRC.CUST_ACCT_ID AND
S_SLS_CRMEM_ITEM.EM_ITEM_NUM =
S_MCK_ACCT_ITEM_PRC.ITEM_NUM)
LEFT OUTER JOIN S_ACCT_CNTRC_LEAD_TYP ON (S_MCK_ACCT_ITEM_PRC.CUST_ACCT_ID =
S_ACCT_CNTRC_LEAD_TYP.CUST_ACCT_ID AND
S_MCK_ACCT_ITEM_PRC.CNTRC_LEAD_ID =
S_ACCT_CNTRC_LEAD_TYP.CNTRC_LEAD_ID)
LEFT OUTER JOIN S_IW_CNTRC_LEAD ON (S_MCK_ACCT_ITEM_PRC.CNTRC_LEAD_ID =
S_IW_CNTRC_LEAD.CNTRC_LEAD_ID)
INNER JOIN S_ACCT_INFO ON (S_SLS_CRMEM_ITEM.CUST_ACCT_ID =
S_ACCT_INFO.CUST_ACCT_ID)
LEFT OUTER JOIN S_VA_CUST_CNTRC ON (S_SLS_CRMEM_ITEM.CUST_ACCT_ID =
S_VA_CUST_CNTRC.CUST_ACCT_ID AND
S_SLS_CRMEM_ITEM.EM_ITEM_NUM =
S_VA_CUST_CNTRC.ITEM_NUM)
INNER JOIN S_MCK_ITEM ON (S_SLS_CRMEM_ITEM.EM_ITEM_NUM =
S_MCK_ITEM.EM_ITEM_NUM)
where ((((((((S_SLS_CRMEM_ITEM.CUST_ACCT_ID in ('110718') or
(S_ACCT_INFO.NATL_GRP_CD = '0227' and
S_ACCT_INFO.NATL_SUB_GRP_CD = '000001')) or
(S_ACCT_INFO.NATL_GRP_CD = '0227' and
S_ACCT_INFO.NATL_SUB_GRP_CD = '000002')) or
(S_ACCT_INFO.NATL_GRP_CD = '0227' and
S_ACCT_INFO.NATL_SUB_GRP_CD = '000003')) or
(S_ACCT_INFO.NATL_GRP_CD = '0227' and
S_ACCT_INFO.NATL_SUB_GRP_CD = '000005')) or
(S_ACCT_INFO.CUST_CHN_ID = '227' and
S_ACCT_INFO.CUST_RGN_NUM = '000001')) or
(S_ACCT_INFO.CUST_CHN_ID = '227' and
S_ACCT_INFO.CUST_RGN_NUM = '000002')) or
(S_ACCT_INFO.CUST_CHN_ID = '227' and
S_ACCT_INFO.CUST_RGN_NUM = '000003')) or
(S_ACCT_INFO.CUST_CHN_ID = '227' and
S_ACCT_INFO.CUST_RGN_NUM = '000005'))
and S_MCK_ITEM.SPLR_ACCT_ID IN
('34227', '34232', '34233', '34228', '34229', '34230', '34231',
'34235', '34236', '78063', '84230', '90014', '98014')
and (S_SLS_CRMEM_ITEM.SLS_PROC_WRK_DT between
to_date('04/01/2007', 'MM/DD/YYYY') and
to_date('06/30/2007', 'MM/DD/YYYY'))
GROUP BY S_ACCT_INFO.CUST_ACCT_NAM,
S_SLS_CRMEM_ITEM.CUST_ACCT_ID,
S_SLS_CRMEM_ITEM.CUST_CNTRC_ID,
S_MCK_ITEM.GNRC_ID,
S_MCK_ITEM.GNRC_NAM,
S_MCK_ITEM.SELL_DSCR_TXT,
S_MCK_ITEM.ITEM_STAT_CD_DSPSTN,
S_MCK_ITEM.RETL_LBL_CNT,
S_MCK_ITEM.LBL_NAM,
S_MCK_ITEM.MFG_SIZ_QTY,
S_SLS_CRMEM_ITEM.EM_ITEM_NUM,
S_MCK_ITEM.NDC_NUM,
S_MCK_ITEM.SPLR_ITEM_SEQ_NUM,
S_MCK_ITEM.SPLR_ACCT_NAM,
S_MCK_ITEM.SPLR_ACCT_ID,
S_MCK_ITEM.UPC_NUM,
S_IW_CNTRC_LEAD.CNTRC_LEAD_NAM,
DECODE(S_SLS_CRMEM_ITEM.CNTRC_LEAD_TP_ID, NULL, 'N', 'Y'),
S_SLS_CRMEM_ITEM.CNTRC_LEAD_TP_ID,
S_SLS_CRMEM_ITEM.SLS_DOC_NUM,
S_SLS_CRMEM_ITEM.SLS_PROC_WRK_DT,
CASE
WHEN S_SLS_CRMEM_ITEM.GRS_SLS_QTY <> 0 THEN
ROUND(S_SLS_CRMEM_ITEM.GRS_SLS_AMT /
S_SLS_CRMEM_ITEM.GRS_SLS_QTY,
2)
ELSE
0
END,
S_SLS_CRMEM_ITEM.CUST_PO_NUM,
S_SLS_CRMEM_ITEM.CUST_OMIT_IND,
S_ACCT_INFO.NATL_SUB_GRP_CD,
S_ACCT_INFO.CUST_STOR_NUM,
S_MCK_ITEM.PKG_SIZ
order by S_MCK_ITEM.NDC_NUM asc,
S_SLS_CRMEM_ITEM.SLS_PROC_WRK_DT asc,
S_SLS_CRMEM_ITEM.SLS_PROC_WRK_DT asc
Similar Messages
-
How to avoid full Table scan when using Rule based optimizer (Oracle817)
1. We have a Oracle 8.1.7 DB, and the optimizer_mode is set to "RULE"
2. There are three indexes on table cm_contract_supply, which is a large table having 28732830 Rows, and average row length 149 Bytes
COLUMN_NAME INDEX_NAME
PROGRESS_RECID XAK11CM_CONTRACT_SUPPLY
COMPANY_CODE XIE1CM_CONTRACT_SUPPLY
CONTRACT_NUMBER XIE1CM_CONTRACT_SUPPLY
COUNTRY_CODE XIE1CM_CONTRACT_SUPPLY
SUPPLY_TYPE_CODE XIE1CM_CONTRACT_SUPPLY
VERSION_NUMBER XIE1CM_CONTRACT_SUPPLY
CAMPAIGN_CODE XIF1290CM_CONTRACT_SUPPLY
COMPANY_CODE XIF1290CM_CONTRACT_SUPPLY
COUNTRY_CODE XIF1290CM_CONTRACT_SUPPLY
SUPPLIER_BP_ID XIF801CONTRACT_SUPPLY
COMMISSION_LETTER_CODE XIF803CONTRACT_SUPPLY
COMPANY_CODE XIF803CONTRACT_SUPPLY
COUNTRY_CODE XIF803CONTRACT_SUPPLY
COMPANY_CODE XPKCM_CONTRACT_SUPPLY
CONTRACT_NUMBER XPKCM_CONTRACT_SUPPLY
COUNTRY_CODE XPKCM_CONTRACT_SUPPLY
SUPPLY_SEQUENCE_NUMBER XPKCM_CONTRACT_SUPPLY
VERSION_NUMBER XPKCM_CONTRACT_SUPPLY
3. We are querying the table for a particular contract_number and version_number. We want to avoid full table scan.
SELECT /*+ INDEX(XAK11CM_CONTRACT_SUPPLY) */
rowid, pms.cm_contract_supply.*
FROM pms.cm_contract_supply
WHERE
contract_number = '0000000000131710'
AND version_number = 3;
However despite of giving hint, query results are fetched after full table scan.
Execution Plan
0 SELECT STATEMENT Optimizer=RULE (Cost=1182 Card=1 Bytes=742)
1 0 TABLE ACCESS (FULL) OF 'CM_CONTRACT_SUPPLY' (Cost=1182 Card=1 Bytes=742)
4. I have tried giving
SELECT /*+ FIRST_ROWS + INDEX(XAK11CM_CONTRACT_SUPPLY) */
rowid, pms.cm_contract_supply.*
FROM pms.cm_contract_supply
WHERE
contract_number = '0000000000131710'
AND version_number = 3;
and
SELECT /*+ CHOOSE + INDEX(XAK11CM_CONTRACT_SUPPLY) */
rowid, pms.cm_contract_supply.*
FROM pms.cm_contract_supply
WHERE
contract_number = '0000000000131710'
AND version_number = 3;
But it does not work.
Is there some way without changing optimizer mode and without creating an additional index, we can use the index instead of full table scan?David,
Here is my test on a Oracle 10g database.
SQL> create table mytable as select * from all_tables;
Table created.
SQL> set autot traceonly
SQL> alter session set optimizer_mode = choose;
Session altered.
SQL> select count(*) from mytable;
Execution Plan
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (FULL) OF 'MYTABLE' (TABLE)
Statistics
1 recursive calls
0 db block gets
29 consistent gets
0 physical reads
0 redo size
223 bytes sent via SQL*Net to client
276 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> analyze table mytable compute statistics;
Table analyzed.
SQL> select count(*) from mytable
2 ;
Execution Plan
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=11 Card=1)
1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (FULL) OF 'MYTABLE' (TABLE) (Cost=11 Card=1
788)
Statistics
1 recursive calls
0 db block gets
29 consistent gets
0 physical reads
0 redo size
222 bytes sent via SQL*Net to client
276 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> disconnect
Disconnected from Oracle Database 10g Enterprise Edition Release 10.1.0.2.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP and Data Mining options -
How can this query avoid full table scans?
It is difficult to avoid full table scans in the following query because the values of column STATUS reiterant numbers. There are only 10 numbers values for the STATUS column (1..10)
But the table is very large. there are more than 1 million rows in it. A full table scanning consumes too much time.
How can this query avoid full table scans?
Thank you
SELECT SYNC,CUS_ID INTO V_SYNC,V_CUS_ID FROM CONSUMER_MSG_IDX
WHERE CUS_ID = V_TYPE_CUS_HEADER.CUS_ID AND
ADDRESS_ID = V_TYPE_CUS_HEADER.ADDRESS_ID AND
STATUS =! 8;Edited by: junez on Jul 23, 2009 7:30 PMYour code had an extra AND. I also replaced the "not equal" operator, which has display problems with the forum software
SELECT SYNC,CUS_ID
INTO V_SYNC,V_CUS_ID
FROM CONSUMER_MSG_IDX
WHERE CUS_ID = V_TYPE_CUS_HEADER.CUS_ID AND
ADDRESS_ID = V_TYPE_CUS_HEADER.ADDRESS_ID AND
STATUS != 8;Are you sure this query is doing a table scan? Is there an index on CUS_ID, ADDRESS_ID? I would think that would be mostly unique. So I'm not sure why you think the STATUS column is causing problems. It would seem to just be a non-selective additional filter.
Justin -
URGENT HELP Required: Solution to avoid Full table scan for a PL/SQL query
Hi Everyone,
When I checked the EXPLAIN PLAN for the below SQL query, I saw that Full table scans is going on both the tables TABLE_A and TABLE_B
UPDATE TABLE_A a
SET a.current_commit_date =
(SELECT MAX (b.loading_date)
FROM TABLE_B b
WHERE a.sales_order_id = b.sales_order_id
AND a.sales_order_line_id = b.sales_order_line_id
AND b.confirmed_qty > 0
AND b.data_flag IS NULL
OR b.schedule_line_delivery_date >= '23 NOV 2008')
Though the TABLE_A is a small table having nearly 1 lakh records, the TABLE_B is a huge table, having nearly 2 and a half crore records.
I created an Index on the TABLE_B having all its fields used in the WHERE clause. But, still the explain plan is showing FULL TABLE SCAN only.
When I run the query, it is taking long long time to execute (more than 1 day) and each time I have to kill the session.
Please please help me in optimizing this.
Thanks,
SudhindraCheck the instruction again, you're leaving out information we need in order to help you, like optimizer information.
- Post your exact database version, that is: the result of select * from v$version;
- Don't use TOAD's execution plan, but use
SQL> explain plan for <your_query>;
SQL> select * from table(dbms_xplan.display);(You can execute that in TOAD as well).
Don't forget you need to use the {noformat}{noformat} tag in order to post formatted code/output/execution plans etc.
It's also explained in the instruction.
When was the last time statistics were gathered for table_a and table_b?
You can find out by issuing the following query:select table_name
, last_analyzed
, num_rows
from user_tables
where table_name in ('TABLE_A', 'TABLE_B');
Can you also post the results of these counts;select count(*)
from table_b
where confirmed_qty > 0;
select count(*)
from table_b
where data_flag is null;
select count(*)
from table_b
where schedule_line_delivery_date >= /* assuming you're using a date, and not a string*/ to_date('23 NOV 2008', 'dd mon yyyy'); -
Dear all,
While doing a stress testing I found that there was a lot a full table scans due to which there was preformance drop. How can I avoid full table scans. Please suggest some ways as I am in clients place.
Waiting for your help.
Regards and thanks in advance
SLHi SL,
How can I avoid full table scansFull table scans are not always bad! It depends foremost on your optimizer goal (all_rows vs. first_rows), plus your multiblock read count, table size, percentage of rows requested, and many other factors.
Here are my notes:
http://www.dba-oracle.com/art_orafaq_oracle_sql_tune_table_scan.htm
To avoid full table scans, start by running plan9i.sql and then drill-in and see if you have missing indexes:
http://www.dba-oracle.com/t_plan9i_sql_full_table_scans.htm
You can also run the 10g SQLTuning advisor to find missing indexes, and also, don't forget to consider function-based indexes, a great way to eliminate unncessary lage-table full-table scans:
http://www.dba-oracle.com/oracle_tips_index_scan_fbi_sql.htm
Hope this helps. . .
Donald K. Burleson
Oracle Press author -
Full table scan and how to avoid it
Hello,
I have two tables, one with 425,000 records, and the other with 5,200,000 records in it. The smaller table has an index on its unique primary key, and the bigger table has an index on the foreign key of the smaller table.
When joining these two tables, I keep getting full table scans on both of these tables, and I would like to understand the philosophy behind it as well as ways to avoid this.
ThanksAre you manipulating the join columns in any fashion? Such as applying a function to them like in
to_char(column_a) = to_char(column_b)Because any manipulation like that will obviate your index (assuming you don't have function based indexes).
Really though, without your tables, indexes and query, we're left with voodoo, which is cool, but not really that effective.
*note to any and all practicing witch doctors, i really do think voodoo is cool and effective, please don't persecute me for my speakings.
Message was edited by:
Tubby -
How to find the count of tables going for fts(full table scan in oracle 10g
HI
how to find the count of tables going for fts(full table scan) in oracle 10g
regardsHi,
Why do you want to 'find' those tables?
Do you want to 'avoid FTS' on those tables?
You provide little information here. (Perhaps you just migrated from 9i and having problems with certain queries now?)
FTS is sometimes the fastest way to retrieve data, and sometimes an index scan is.
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:9422487749968
There's no 'FTS view' available, if you want to know what happens on your DB you need, like Anand already said, to trace sessions that 'worry you'. -
Slow query due to large table and full table scan
Hi,
We have a large Oracle database, v 10g. Two of the tables in the database have over one million rows.
We have a few queries which take a lot of time to execute. Not always though, it that seems when load is high the queries tend
to take much longer. Average time may be 1 or 2 seconds, but maxtime can be up to 2 minutes.
We have now used Oracle Grid to help us examine the queries. We have found that some of the queries require two or three full table scans.
Two of the full table scans are of the two large tables mentioned above.
This is an example query:
SELECT table1.column, table2.column, table3.column
FROM table1
JOIN table2 on table1.table2Id = table2.id
LEFT JOIN table3 on table2.table3id = table3.id
WHERE table1.id IN(
SELECT id
FROM (
(SELECT a.*, rownum rnum FROM(
SELECT table1.id
FROM table1,
table2,
table3
WHERE
table1.table2id = table2.id
AND
table2.table3id IS NULL OR table2.table3id = :table3IdParameter
) a
WHERE rownum <= :end))
WHERE rnum >= :start
Table1 and table2 are the large tables in this example. This query starts two full table scans on those tables.
Can we avoid this? We have, what we think are, the correct indexes.
/best regards, Håkan>
Hi Håkan - welcome to the forum.
We have a large Oracle database, v 10g. Two of the tables in the database have over one million rows.
We have a few queries which take a lot of time to execute. Not always though, it that seems when load is high the queries tend
to take much longer. Average time may be 1 or 2 seconds, but maxtime can be up to 2 minutes.
We have now used Oracle Grid to help us examine the queries. We have found that some of the queries require two or three full table scans.
Two of the full table scans are of the two large tables mentioned above.
This is an example query:Firstly, please read the forum FAQ - top right of page.
Please format your SQL using tags [code /code].
In order to help us to help you.
Please post table structures - relevant (i.e. joined, FK, PK fields only) in the form - note use of code tags - we can just run table create script.
CREATE TABLE table1
Field1 Type1,
Field2 Type2,
FieldN TypeN
);Then give us some table data - not 100's of records - just enough in the form
INSERT INTO Table1 VALUES(Field1, Field2.... FieldN);
..Please post EXPLAIN PLAN - again with tags.
HTH,
Paul...
/best regards, Håkan -
Hi, Folks:
I have a complex SQL statement that runs very slowly.
Following is the statement:
SELECT
T3.POSITION_ID,
T12.PR_POSTN_ID,
T12.PR_TERR_ID,
T12.PR_REP_MANL_FLG,
T9.CREATED,
T10.PR_EMP_ID,
T9.MODIFICATION_NUM,
T12.DEDUP_TOKEN,
T12.LOCATION_LEVEL,
T12.PR_PRTNR_OU_ID,
T12.PR_OU_TYPE_ID,
T12.PAR_DUNS_NUM,
T3.ACCNT_NAME,
T11.ATTRIB_16,
T6.PAR_ROW_ID,
T3.INVSTR_FLG,
T6.ROW_ID,
T12.DUNS_NUM,
T12.BU_ID,
T10.ROW_ID,
T2.LAST_NAME,
T3.SRV_PROVDR_FLG,
T12.X_PR_MERCH_NBR_ID,
T3.ROW_STATUS,
T12.NAME,
T11.PAR_ROW_ID,
T6.LAST_UPD_BY,
T6.MODIFICATION_NUM,
T3.PRIORITY_FLG,
T10.NAME,
T3.ASGN_SYS_FLG,
T9.PROFIT,
T12.PR_BL_ADDR_ID,
T12.PR_REP_ASGN_TYPE,
T9.LAST_UPD_BY,
T3.FACILITY_FLG,
T12.LAST_UPD_BY,
T12.PR_SHIP_ADDR_ID,
T11.MODIFICATION_NUM,
T11.LAST_UPD_BY,
T5.LOGIN,
T3.ASGN_MANL_FLG
FROM
S_ADDR_ORG T1,
S_CONTACT T2,
S_ACCNT_POSTN T3,
S_ORG_INT T4,
S_EMPLOYEE T5,
S_ORG_EXT_FNX T6,
S_ORG_SYN T7,
S_INDUST T8,
S_ORG_EXT_T T9,
S_POSTN T10,
S_ORG_EXT_X T11,
S_ORG_EXT T12
WHERE
T12.BU_ID = T4.ROW_ID (+) AND
T12.PR_CON_ID = T2.ROW_ID (+) AND
T12.ROW_ID = T7.OU_ID AND
T12.ROW_ID = T11.PAR_ROW_ID (+) AND
T12.ROW_ID = T6.PAR_ROW_ID (+) AND
T12.ROW_ID = T9.PAR_ROW_ID (+) AND
T12.PR_INDUST_ID = T8.ROW_ID (+) AND
T12.PR_ADDR_ID = T1.ROW_ID (+) AND
T12.PR_POSTN_ID = T10.ROW_ID AND
T12.PR_POSTN_ID = T3.POSITION_ID AND
T12.ROW_ID = T3.OU_EXT_ID AND
T10.PR_EMP_ID = T5.ROW_ID (+) AND
(T12.X_BMO_CUST_FLG = 'Y') AND
(T7.NAME IS NULL );
***** SQL Statement Execute Time: 31.703 seconds *****
I do a explain plan and found the table S_ORG_EXT (T12)
get a full table scan.
But I found the table S_ORG_EXT did have lots of indexes
build on each column shown in the where statement.
Our database use RULE base optimizer and it should use
index instead of full table scan.
Then, I look at this SQL and realize it is a star query.
One more thing is that the table S_ORG_SYN (T7) defined
the column NAME as NOT NULL. If the query process, it
should return no row.
But I still don't know for what reason the Oracle use
full table scan and ignore the S_ORG_SYN.NAME should be
NOT NULL
If I want to avoid the full table scan, how can I do by
not switching to COST base optimizer mode ?
Thanks,
KeMichael:
A nice explanantion. In my experience, in versions up to 8.1.7, the RBO seems to be faster in the large majority of queries than the CBO. In our payroll application (version 8.0.5), removing statistics cut the time for the calculation run from 6.5 hours to under 2.
The CBO seems to be significantly faster in 9i. We only have one application currently running in a 9.0.1 database. In this app, a large stored procedure took about 2 minutes to run when there were no statistics, and about 10 seconds after we analyzed the tables.
As more of our vendors migrate to 9 (we just got the last vendor migrated off 7.3 to 8.0.6 a couple of months ago), I may become a bigger fan of the CBO. John,
I remember having a discussion with you about the CBO in a thread once and am aware of your opinion of the CBO. My opinion has been test which works for you RBO or CBO - in our case we verified that CBO worked better for us. Anyway, I was searching metalink and it looks like you'll be forced to become a "bigger fan" of the CBO after 9i release 2. This is from part of Doc ID 189702.1 on metalink:
The rule-based optimizer (RBO) will be no longer be a valid optimization choice when Oracle9i is de-supported. The release after Oracle9i
(referred to in this article as Oracle10i) will only support the cost-based optimizer (CBO). Hence Oracle9i Release 2 is the last releases to
contain the RBO. Partners and customers should certify their applications with the CBO before that time.
...but of course Oracle has been warning people of the demise of the RBO for some time.
Al -
Why it is taking full table scan when index is available
Hi all,
I am facing a strange problem with index.
I created index on a column like
1. CREATE INDEX ASSETS_ARTIST_IDX2 ON ASSETS(artist).
SELECT asset.artist AS NAME FROM ASSETS asset WHERE asset.artist LIKE 'J%'
Explain Plan : INDEX RANGE SCAN
2. CREATE INDEX ASSETS_ARTIST_IDX2 ON ASSETS(UPPER (TRANSLATE (artist, ',;:"', ' ')));
SELECT asset.artist AS NAME FROM ASSETS asset WHERE UPPER (TRANSLATE (artist, ',;:"', ' ')) LIKE 'J%'
Explain Plan : TABLE ACCESS FULL
first time it is taking index range scan,but in second situation scaning full table.Please let me know how to avoid the full table scan.
Regards,
RajasekharActually, I misseunderstood damorgan' s statement about NULL and OP did not provide table definition. So based on FTS I would say it is more likely column is NULLable, otherwise I would expect INDEX FAST SCAN:
SQL> create table emp1 as select * from emp
2 /
Table created.
SQL> create index emp1_idx1 on emp1(empno)
2 /
Index created.
SQL> exec dbms_stats.gather_table_stats('SCOTT','EMP1');
PL/SQL procedure successfully completed.
SQL> desc emp1
Name Null? Type
EMPNO NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2)
SQL> explain plan for
2 select empno
3 from emp1 where UPPER(TRANSLATE(empno, ',;:"', ' ')) LIKE '7%'
4 /
Explained.
SQL> @?\rdbms\admin\utlxpls
PLAN_TABLE_OUTPUT
Plan hash value: 2226897347
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 4 | 3 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| EMP1 | 1 | 4 | 3 (0)| 00:00:01 |
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
1 - filter(UPPER(TRANSLATE(TO_CHAR("EMPNO"),',;:"',' ')) LIKE '7%')
13 rows selected.
SQL> alter table emp1 modify empno not null
2 /
Table altered.
SQL> explain plan for
2 select empno
3 from emp1 where UPPER(TRANSLATE(empno, ',;:"', ' ')) LIKE '7%'
4 /
Explained.
SQL> @?\rdbms\admin\utlxpls
PLAN_TABLE_OUTPUT
Plan hash value: 2850860361
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 4 | 1 (0)| 00:00:01 |
|* 1 | INDEX FULL SCAN | EMP1_IDX1 | 1 | 4 | 1 (0)| 00:00:01 |
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
1 - filter(UPPER(TRANSLATE(TO_CHAR("EMPNO"),',;:"',' ')) LIKE '7%')
13 rows selected.
SQL> SY. -
Cursors - More number of repeated full table scans
Hai,
If i execute the below mentioned query in sql*plus
select distinct cod_acct_no, a.cod_cc_brn, a.cod_prod
from account_master a, product_master b
where a.prod_no = b.prod_no
and b.cod_sc_pkg = var_pi_cod_sc_pkg
and cod_acct_stat not in ( 1,5)
UNION
select distinct a.cod_acct_no, a.cod_cc_brn, a.cod_prod
from account_master a, charge_account sc
where sc.cod_acct_no = a.cod_acct_no
and sc.cod_sc_pkg = var_pi_cod_sc_pkg
and cod_acct_stat not in ( 1,5)
I am getting results within a minute. Account_master is the big table in this join. And only one full table scan is happening for this table.
IF the same query is used in pl/sql cursors, it is taking very long time and after analysis, it was found that multiple times of FTS is happening for account_master table. Why it is happening ? Any help pls.
Regards
SridharHi,
First thing, you don't need to issue a distinct for each Select section in a Union: Union automatically does that, by sorting and returning distinct values of both result sets combined.
But most importantly, the performance is poor because you're running a loop, not because the query itself is any worse than what it was in SQL*Plus.
When you run a cursor for loop, the PL/SQL engine has to switch context to the SQL engine repeatedly to fetch the next row, one at a time, and even though you may
not notice a performance degradation when you have a small resultset, as it scales up the problem becomes more visible.
What is it you're performing inside the loop?
Bottom line is you should avoid the cursor for loop solution and do it in a single statement or at least using bulk collect/forall operations, that should increase your performance dramatically.
If you can post a little more about your problem, instead the solution you initially thought of, it would help us help you. Basically please provide us your Oracle version, table structures and sample data for them,
along with an expected output or data manipulation.
Regards,
Sitja. -
Data Federator Full Table scan
Hi,
Is it possible to prevent a Full table scan when creating a join between tables of 2 catalogues in a Data Federator?
This is seriously hampering the development time within Data Federator Development.
I am working with IDT Beta to create a Universe based on Multiple Source. The delay is so huge when creating joins that we could revert to Universe Design Tool. I have posted it here as Data Federator gurus will have tweak about IDT as it incorporates DF within itself in BI 4.0.
Any inputs will be great.. In case this is in the wrong forums, then please move it accordingly.
VFernandesThe issue was fixed when the GA was released. This was present in Beta
-
Select statement in a function does Full Table Scan
All,
I have been coding a stored procedure that writes 38K rows in less than a minute. If I add another column which requires call to a package and 4 functions within that package, it runs for about 4 hours. I have confirmed that due to problems in one of the functions, the code does full table scans. The package and all of its functions were written by other contractors who have been long gone.
Please note that case_number_in (VARCHAR2) and effective_date_in (DATE) are parameters sent to the problem function and I have verified through TOAD’s debugger that their values are correct.
Table named ps2_benefit_register has over 40 million rows but case_number is an index for that table.
Table named ps1_case_fs has more than 20 million rows but also uses case_number as an index.
Select #1 – causes full table scan runs and writes 38K rows in a couple of hours.
{case}
SELECT max(a2.application_date)
INTO l_app_date
FROM dwfssd.ps2_benefit_register a1, dwfssd.ps2_case_fs a2
WHERE a2.case_number = case_number_in and
a1.case_number = a2.case_number and
a2.application_date <= effective_date_in and
a1.DOCUMENT_TYPE = 'F';
{case}
Select #2 – runs – hard coding values makes the code to write the same 38K rows in a few minutes.
{case}
SELECT max(a2.application_date)
INTO l_app_date
FROM dwfssd.ps2_benefit_register a1, dwfssd.ps2_case_fs a2
WHERE a2.case_number = 'A006438' and
a1.case_number = a2.case_number and
a2.application_date <= '01-Apr-2009' and
a1.DOCUMENT_TYPE = 'F';
{case}
Why using the values in the passed parameter in the first select statement causes full table scan?
Thank you for your help,
Seyed
Edited by: user11117178 on Jul 30, 2009 6:22 AM
Edited by: user11117178 on Jul 30, 2009 6:23 AM
Edited by: user11117178 on Jul 30, 2009 6:24 AMHello Dan,
Thank you for your input. The function is not determinsitic, therefore, I am providing you with the explain plan. By version number, if you are refering to the Database version, we are running 10g.
PLAN_TABLE_OUTPUT
Plan hash value: 2132048964
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
| 0 | SELECT STATEMENT | | 324K| 33M| 3138 (5)| 00:00:38 | | |
|* 1 | HASH JOIN | | 324K| 33M| 3138 (5)| 00:00:38 | | |
| 2 | BITMAP CONVERSION TO ROWIDS | | 3 | 9 | 1 (0)| 00:00:01 | | |
|* 3 | BITMAP INDEX FAST FULL SCAN| IDX_PS2_ACTION_TYPES | | | | | | |
| 4 | PARTITION RANGE ITERATOR | | 866K| 87M| 3121 (4)| 00:00:38 | 154 | 158 |
| 5 | TABLE ACCESS FULL | PS2_FS_TRANSACTION_FACT | 866K| 87M| 3121 (4)| 00:00:38 | 154 | 158 |
Predicate Information (identified by operation id):
1 - access("AL1"."ACTION_TYPE_ID"="AL2"."ACTION_TYPE_ID")
3 - filter("AL2"."ACTION_TYPE"='1' OR "AL2"."ACTION_TYPE"='2' OR "AL2"."ACTION_TYPE"='S')
Thank you very much,
Seyed -
Preventing Discoverer using Full Table Scans with Decode in a View
Hi Forum,
Hope you are can help, it involves a performance issues when creating a Report / Query in Discoverer.
I have a Discoverer Report that currently takes less than 5 seconds to run. After I add a condition to bring back Batch Status that = Posted we cancelled the query after reaching 20 minutes as this is way too long. If I remove the condition the query time goes back to less than 5 seconds. Changing the condition to Batch Status that = Unposted returns the query in seconds.
Ive been doing some digging and have found the database view that is linked to the Journal Batches folder in Discoverer. See at end of post.
I think the problem is with the column using DECODE. When querying the column in TOAD the value of P is returned. But in discoverer the condition is done on the value Posted. Im not too sure how DECODE works, but think this could be the causing some sort of issue with Full Table Scans.
Any idea how do we get around this?
SELECT
JOURNAL_BATCH1.JE_BATCH_ID,
JOURNAL_BATCH1.NAME,
JOURNAL_BATCH1.SET_OF_BOOKS_ID,
GL_SET_OF_BOOKS.NAME,
DECODE( JOURNAL_BATCH1.STATUS,
'+', 'Unable to validate or create CTA',
'+*', 'Was unable to validate or create CTA',
'-','Invalid or inactive rounding differences account in journal entry',
'-*', 'Modified invalid or inactive rounding differences account in journal entry',
'<', 'Showing sequence assignment failure',
'<*', 'Was showing sequence assignment failure',
'>', 'Showing cutoff rule violation',
'>*', 'Was showing cutoff rule violation',
'A', 'Journal batch failed funds reservation',
'A*', 'Journal batch previously failed funds reservation',
'AU', 'Showing batch with unopened period',
'B', 'Showing batch control total violation',
'B*', 'Was showing batch control total violation',
'BF', 'Showing batch with frozen or inactive budget',
'BU', 'Showing batch with unopened budget year',
'C', 'Showing unopened reporting period',
'C*', 'Was showing unopened reporting period',
'D', 'Selected for posting to an unopened period',
'D*', 'Was selected for posting to an unopened period',
'E', 'Showing no journal entries for this batch',
'E*', 'Was showing no journal entries for this batch',
'EU', 'Showing batch with unopened encumbrance year',
'F', 'Showing unopened reporting encumbrance year',
'F*', 'Was showing unopened reporting encumbrance year',
'G', 'Showing journal entry with invalid or inactive suspense account',
'G*', 'Was showing journal entry with invalid or inactive suspense account',
'H', 'Showing encumbrance journal entry with invalid or inactive reserve account',
'H*', 'Was showing encumbrance journal entry with invalid or inactive reserve account',
'I', 'In the process of being posted',
'J', 'Showing journal control total violation',
'J*', 'Was showing journal control total violation',
'K', 'Showing unbalanced intercompany journal entry',
'K*', 'Was showing unbalanced intercompany journal entry',
'L', 'Showing unbalanced journal entry by account category',
'L*', 'Was showing unbalanced journal entry by account category',
'M', 'Showing multiple problems preventing posting of batch',
'M*', 'Was showing multiple problems preventing posting of batch',
'N', 'Journal produced error during intercompany balance processing',
'N*', 'Journal produced error during intercompany balance processing',
'O', 'Unable to convert amounts into reporting currency',
'O*', 'Was unable to convert amounts into reporting currency',
'P', 'Posted',
'Q', 'Showing untaxed journal entry',
'Q*', 'Was showing untaxed journal entry',
'R', 'Showing unbalanced encumbrance entry without reserve account',
'R*', 'Was showing unbalanced encumbrance entry without reserve account',
'S', 'Already selected for posting',
'T', 'Showing invalid period and conversion information for this batch',
'T*', 'Was showing invalid period and conversion information for this batch',
'U', 'Unposted',
'V', 'Journal batch is unapproved',
'V*', 'Journal batch was unapproved',
'W', 'Showing an encumbrance journal entry with no encumbrance type',
'W*', 'Was showing an encumbrance journal entry with no encumbrance type',
'X', 'Showing an unbalanced journal entry but suspense not allowed',
'X*', 'Was showing an unbalanced journal entry but suspense not allowed',
'Z', 'Showing invalid journal entry lines or no journal entry lines',
'Z*', 'Was showing invalid journal entry lines or no journal entry lines', NULL ),
DECODE( JOURNAL_BATCH1.ACTUAL_FLAG, 'A', 'Actual', 'B', 'Budget', 'E', 'Encumbrance', NULL ),
JOURNAL_BATCH1.DEFAULT_PERIOD_NAME,
JOURNAL_BATCH1.POSTED_DATE,
JOURNAL_BATCH1.DATE_CREATED,
JOURNAL_BATCH1.DESCRIPTION,
DECODE( JOURNAL_BATCH1.AVERAGE_JOURNAL_FLAG, 'N', 'Standard', 'Y', 'Average', NULL ),
DECODE( JOURNAL_BATCH1.BUDGETARY_CONTROL_STATUS, 'F', 'Failed', 'I', 'In Process', 'N', 'N/A', 'P', 'Passed', 'R', 'Required', NULL ),
DECODE( JOURNAL_BATCH1.APPROVAL_STATUS_CODE, 'A', 'Approved', 'I', 'In Process', 'J', 'Rejected', 'R', 'Required', 'V','Validation Failed','Z', 'N/A',NULL ),
JOURNAL_BATCH1.CONTROL_TOTAL,
JOURNAL_BATCH1.RUNNING_TOTAL_DR,
JOURNAL_BATCH1.RUNNING_TOTAL_CR,
JOURNAL_BATCH1.RUNNING_TOTAL_ACCOUNTED_DR,
JOURNAL_BATCH1.RUNNING_TOTAL_ACCOUNTED_CR,
JOURNAL_BATCH1.PARENT_JE_BATCH_ID,
JOURNAL_BATCH2.NAME
FROM
GL_JE_BATCHES JOURNAL_BATCH1,
GL_JE_BATCHES JOURNAL_BATCH2,
GL_SETS_OF_BOOKS
GL_SET_OF_BOOKS
WHERE
JOURNAL_BATCH1.PARENT_JE_BATCH_ID = JOURNAL_BATCH2.JE_BATCH_ID (+) AND
JOURNAL_BATCH1.SET_OF_BOOKS_ID = GL_SET_OF_BOOKS.SET_OF_BOOKS_ID AND
GL_SECURITY_PKG.VALIDATE_ACCESS( JOURNAL_BATCH1.SET_OF_BOOKS_ID ) = 'TRUE' WITH READ ONLY
Thanks,
LanceDiscoverer created it's own SQL.
Please see below the SQL Inspector Plan:
Before Condition
SELECT STATEMENT
SORT GROUP BY
VIEW SYS
SORT GROUP BY
NESTED LOOPS OUTER
NESTED LOOPS OUTER
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS OUTER
NESTED LOOPS OUTER
NESTED LOOPS
NESTED LOOPS OUTER
NESTED LOOPS OUTER
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
TABLE ACCESS BY INDEX ROWID GL.GL_CODE_COMBINATIONS
AND-EQUAL
INDEX RANGE SCAN GL.GL_CODE_COMBINATIONS_N2
INDEX RANGE SCAN GL.GL_CODE_COMBINATIONS_N1
TABLE ACCESS BY INDEX ROWID APPLSYS.FND_FLEX_VALUES
INDEX RANGE SCAN APPLSYS.FND_FLEX_VALUES_N1
TABLE ACCESS BY INDEX ROWID APPLSYS.FND_FLEX_VALUE_SETS
INDEX UNIQUE SCAN APPLSYS.FND_FLEX_VALUE_SETS_U1
TABLE ACCESS BY INDEX ROWID APPLSYS.FND_FLEX_VALUES_TL
INDEX UNIQUE SCAN APPLSYS.FND_FLEX_VALUES_TL_U1
INDEX RANGE SCAN APPLSYS.FND_FLEX_VALUE_NORM_HIER_U1
TABLE ACCESS BY INDEX ROWID GL.GL_JE_LINES
INDEX RANGE SCAN GL.GL_JE_LINES_N1
INDEX UNIQUE SCAN GL.GL_JE_HEADERS_U1
INDEX UNIQUE SCAN GL.GL_SETS_OF_BOOKS_U2
TABLE ACCESS BY INDEX ROWID GL.GL_JE_HEADERS
INDEX UNIQUE SCAN GL.GL_JE_HEADERS_U1
INDEX UNIQUE SCAN GL.GL_DAILY_CONVERSION_TYPES_U1
TABLE ACCESS BY INDEX ROWID GL.GL_JE_SOURCES_TL
INDEX UNIQUE SCAN GL.GL_JE_SOURCES_TL_U1
INDEX UNIQUE SCAN GL.GL_JE_CATEGORIES_TL_U1
INDEX UNIQUE SCAN GL.GL_JE_HEADERS_U1
INDEX UNIQUE SCAN GL.GL_JE_HEADERS_U1
INDEX UNIQUE SCAN GL.GL_JE_BATCHES_U1
INDEX UNIQUE SCAN GL.GL_BUDGET_VERSIONS_U1
INDEX UNIQUE SCAN GL.GL_ENCUMBRANCE_TYPES_U1
INDEX UNIQUE SCAN GL.GL_SETS_OF_BOOKS_U2
TABLE ACCESS BY INDEX ROWID GL.GL_JE_BATCHES
INDEX UNIQUE SCAN GL.GL_JE_BATCHES_U1
INDEX UNIQUE SCAN GL.GL_SETS_OF_BOOKS_U2
INDEX UNIQUE SCAN GL.GL_JE_BATCHES_U1
TABLE ACCESS BY INDEX ROWID GL.GL_PERIODS
INDEX RANGE SCAN GL.GL_PERIODS_U1
After Condition
SELECT STATEMENT
SORT GROUP BY
VIEW SYS
SORT GROUP BY
NESTED LOOPS
NESTED LOOPS OUTER
NESTED LOOPS OUTER
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS OUTER
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS OUTER
NESTED LOOPS
NESTED LOOPS OUTER
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS OUTER
NESTED LOOPS
TABLE ACCESS FULL GL.GL_JE_BATCHES
INDEX UNIQUE SCAN GL.GL_SETS_OF_BOOKS_U2
INDEX UNIQUE SCAN GL.GL_JE_BATCHES_U1
TABLE ACCESS BY INDEX ROWID GL.GL_JE_HEADERS
INDEX RANGE SCAN GL.GL_JE_HEADERS_N1
INDEX UNIQUE SCAN GL.GL_SETS_OF_BOOKS_U2
INDEX UNIQUE SCAN GL.GL_ENCUMBRANCE_TYPES_U1
INDEX UNIQUE SCAN GL.GL_DAILY_CONVERSION_TYPES_U1
INDEX UNIQUE SCAN GL.GL_BUDGET_VERSIONS_U1
TABLE ACCESS BY INDEX ROWID GL.GL_JE_SOURCES_TL
INDEX UNIQUE SCAN GL.GL_JE_SOURCES_TL_U1
INDEX UNIQUE SCAN GL.GL_JE_CATEGORIES_TL_U1
INDEX UNIQUE SCAN GL.GL_JE_BATCHES_U1
TABLE ACCESS BY INDEX ROWID GL.GL_JE_LINES
INDEX RANGE SCAN GL.GL_JE_LINES_U1
INDEX UNIQUE SCAN GL.GL_SETS_OF_BOOKS_U2
TABLE ACCESS BY INDEX ROWID GL.GL_CODE_COMBINATIONS
INDEX UNIQUE SCAN GL.GL_CODE_COMBINATIONS_U1
TABLE ACCESS BY INDEX ROWID GL.GL_PERIODS
INDEX RANGE SCAN GL.GL_PERIODS_U1
TABLE ACCESS BY INDEX ROWID APPLSYS.FND_FLEX_VALUES
INDEX RANGE SCAN APPLSYS.FND_FLEX_VALUES_N1
INDEX RANGE SCAN APPLSYS.FND_FLEX_VALUE_NORM_HIER_U1
TABLE ACCESS BY INDEX ROWID APPLSYS.FND_FLEX_VALUES_TL
INDEX UNIQUE SCAN APPLSYS.FND_FLEX_VALUES_TL_U1
TABLE ACCESS BY INDEX ROWID APPLSYS.FND_FLEX_VALUE_SETS
INDEX UNIQUE SCAN APPLSYS.FND_FLEX_VALUE_SETS_U1
INDEX UNIQUE SCAN GL.GL_JE_HEADERS_U1
INDEX UNIQUE SCAN GL.GL_JE_HEADERS_U1
INDEX UNIQUE SCAN GL.GL_JE_HEADERS_U1
_________________________________ -
How can i make the optimiser to skip this full table scan ??
Hi,
I am trying to tune the below query, I have checked up all the possibilities to skip the full table scan on vhd_calldesh_archive, But am unable to find the predicate in the where clause, which is letting the optimiser to choose the full table scan on vhd_calldesk_archive table, which is very large one. how can i make the optimiser to skip this full table scan.
Please check the below sql script and explain plan ,
SELECT a.call_id, a.entry_date,
NVL (INITCAP (b.full_name), caller_name) AS caller_name,
c.description AS org_desc, a.env_id, i.env_desc, a.appl_id,
d.appl_desc, a.module_id, e.module_desc, a.call_type_id,
f.call_type_desc, a.priority, a.upduserid,
INITCAP (g.full_name) AS lastupdated_username, a.call_desc, h.mode_desc,
a.received_time,a.assignment_team, a.status,
ROUND (lcc.pkg_com.fn_datediff ('MI',
a.entry_date,
a.status_date
) AS elapsed_time,
ROUND (lcc.pkg_com.fn_datediff ('MI',
a.entry_date,
a.status_date
) AS resolved_min,
CASE
WHEN a.orgid in (1,100,200) THEN a.orgid
ELSE j.regionorgid
END AS region
,(SELECT coalesce(MAX(upddate),a.upddate) FROM lcc.vhd_callstatus stat WHERE stat.call_id = a.call_id
) as stat_upddate
,(SELECT team_desc from lcc.vhd_teams t where t.team_id = a.assignment_team) as team_desc
,a.eta_date
,coalesce(a.caller_contact, b.telephone) AS caller_contact
,coalesce(a.caller_email, b.email) as email
,a.affected_users
,a.outage_time
,a.QA_DONE
,a.LAST_ACTION_TEAM
,a.LAST_ACTION_USER
,INITCAP (k.full_name) AS last_action_username
,a.last_action_date
,l.team_desc as last_action_teamdesc
,a.refid
,INITCAP (lu.full_name) AS logged_name
,a.pmreview
,a.status as main_status
FROM lcc.vhd_calldesk_archive a
LEFT OUTER JOIN lcc.lcc_userinfo_details b ON b.user_name = a.caller_id
INNER JOIN lcc.com_organization c ON c.code = a.orgid
INNER JOIN lcc.vhd_applications d ON d.appl_id = a.appl_id
INNER JOIN lcc.vhd_modules e ON e.appl_id = a.appl_id AND e.module_id = a.module_id
INNER JOIN lcc.vhd_calltypes f ON f.call_type_id = a.call_type_id
INNER JOIN lcc.com_rptorganization j ON j.orgid = a.orgid AND j.tree = 'HLPDK'
LEFT OUTER JOIN lcc.lcc_userinfo_details g ON g.user_name = a.upduserid
LEFT OUTER JOIN lcc.vhd_callmode h ON h.mode_id = a.mode_id
LEFT OUTER JOIN lcc.vhd_environment i ON i.appl_id = a.appl_id AND i.env_id = a.env_id
LEFT OUTER JOIN lcc.lcc_userinfo_details k ON k.user_name = a.last_action_user
LEFT OUTER JOIN lcc.vhd_teams l ON l.team_id = a.last_action_user
LEFT OUTER JOIN (select CALL_ID,upduserid FROM lcc.VHD_CALLDESK_HISTORY P where upddate
in ( select min(upddate) from lcc.VHD_CALLDESK_HISTORY Q WHERE Q.CALL_ID = P.CALL_ID
group by call_id)) ku
ON ku.call_id = a.call_id
LEFT OUTER JOIN lcc.lcc_userinfo_details lu ON NVL(ku.upduserid,A.upduserid) = lu.user_name;
| Id | Operation | Name | Rows | Bytes | Cost |
| 0 | SELECT STATEMENT | | 2104 | 3667K| 37696 |
| 1 | UNION-ALL | | | | |
| 2 | NESTED LOOPS OUTER | | 2103 | 3665K| 37683 |
| 3 | VIEW | | 2103 | 3616K| 35580 |
| 4 | NESTED LOOPS OUTER | | 2103 | 823K| 35580 |
| 5 | NESTED LOOPS OUTER | | 2103 | 774K| 33477 |
| 6 | NESTED LOOPS OUTER | | 2103 | 685K| 31374 |
| 7 | NESTED LOOPS | | 2103 | 636K| 29271 |
| 8 | NESTED LOOPS | | 2103 | 603K| 27168 |
| 9 | NESTED LOOPS OUTER | | 2103 | 558K| 25065 |
| 10 | NESTED LOOPS OUTER | | 2103 | 515K| 22962 |
| 11 | NESTED LOOPS | | 2103 | 472K| 20859 |
| 12 | NESTED LOOPS | | 2103 | 429K| 18756 |
| 13 | NESTED LOOPS OUTER | | 4826 | 890K| 13930 |
| 14 | NESTED LOOPS OUTER | | 4826 | 848K| 9104 |
| 15 | NESTED LOOPS | | 4826 | 754K| 4278 |
|* 16 | TABLE ACCESS FULL | COM_RPTORGANIZATION | 75 | 1050 | 3 |
| 17 | TABLE ACCESS BY INDEX ROWID | VHD_CALLDESK | 64 | 9344 | 57 |
|* 18 | INDEX RANGE SCAN | VHD_CALLDSK_ORGID | 2476 | | 7 |
| 19 | VIEW PUSHED PREDICATE | | 1 | 20 | 1 |
|* 20 | FILTER | | | | |
| 21 | TABLE ACCESS BY INDEX ROWID | VHD_CALLDESK_HISTORY | 1 | 20 | 2 |
|* 22 | INDEX RANGE SCAN | VHD_CALLDSK_HIST_CALLID_IDX | 1 | | 1 |
|* 23 | FILTER | | | | |
| 24 | SORT GROUP BY NOSORT | | 1 | 12 | 2 |
| 25 | TABLE ACCESS BY INDEX ROWID | VHD_CALLDESK_HISTORY | 1 | 12 | 2 |
|* 26 | INDEX RANGE SCAN | VHD_CALLDSK_HIST_CALLID_IDX | 1 | | 1 |
| 27 | TABLE ACCESS BY INDEX ROWID | VHD_CALLMODE | 1 | 9 | 1 |
|* 28 | INDEX UNIQUE SCAN | VHD_CALLMOD_MODID_PK | 1 | | |
| 29 | TABLE ACCESS BY INDEX ROWID | VHD_APPLICATIONS | 1 | 20 | 1 |
|* 30 | INDEX UNIQUE SCAN | VHD_APPL_APPLID_PK | 1 | | |
| 31 | TABLE ACCESS BY INDEX ROWID | VHD_CALLTYPES | 1 | 21 | 1 |
|* 32 | INDEX UNIQUE SCAN | VHD_CALLTYP_ID_PK | 1 | | |
| 33 | TABLE ACCESS BY INDEX ROWID | VHD_TEAMS | 1 | 21 | 1 |
|* 34 | INDEX UNIQUE SCAN | VHD_TEAMID_PK | 1 | | |
| 35 | TABLE ACCESS BY INDEX ROWID | VHD_ENVIRONMENT | 1 | 21 | 1 |
|* 36 | INDEX UNIQUE SCAN | VHD_ENV_APLENVID_PK | 1 | | |
| 37 | TABLE ACCESS BY INDEX ROWID | VHD_MODULES | 1 | 22 | 1 |
|* 38 | INDEX UNIQUE SCAN | VHD_MOD_APLMOD_ID_PK | 1 | | |
| 39 | TABLE ACCESS BY INDEX ROWID | COM_ORGANIZATION | 1 | 16 | 1 |
|* 40 | INDEX UNIQUE SCAN | COM_ORG_PK | 1 | | |
| 41 | TABLE ACCESS BY INDEX ROWID | LCC_USERINFO_DETAILS | 1 | 24 |
|* 42 | INDEX UNIQUE SCAN | LCCUSERINFOIND | 1 | | |
| 43 | TABLE ACCESS BY INDEX ROWID | LCC_USERINFO_DETAILS | 1 | 43 |
|* 44 | INDEX UNIQUE SCAN | LCCUSERINFOIND | 1 | | |
| 45 | TABLE ACCESS BY INDEX ROWID | LCC_USERINFO_DETAILS | 1 | 24 | 1
|* 46 | INDEX UNIQUE SCAN | LCCUSERINFOIND | 1 | | |
| 47 | TABLE ACCESS BY INDEX ROWID | LCC_USERINFO_DETAILS | 1 | 24 | 1
|* 48 | INDEX UNIQUE SCAN | LCCUSERINFOIND | 1 | | |
| 49 | NESTED LOOPS OUTER | | 1 | 1785 | 13 |
| 50 | VIEW | | 1 | 1761 | 12 |
| 51 | NESTED LOOPS OUTER | | 1 | 1656 | 12 |
| 52 | NESTED LOOPS OUTER | | 1 | 1632 | 11 |
| 53 | NESTED LOOPS OUTER | | 1 | 1608 | 10 |
| 54 | NESTED LOOPS | | 1 | 1565 | 9 |
| 55 | NESTED LOOPS | | 1 | 1549 | 9 |
| 56 | NESTED LOOPS | | 1 | 1535 | 9 |
| 57 | NESTED LOOPS OUTER | | 1 | 1513 | 8 |
| 58 | NESTED LOOPS OUTER | | 1 | 1492 | 7 |
| 59 | NESTED LOOPS | | 1 | 1471 | 6 |
| 60 | NESTED LOOPS | | 1 | 1450 | 5 |
| 61 | NESTED LOOPS OUTER | | 1 | 1430 | 4 |
| 62 | NESTED LOOPS OUTER | | 1 | 1421 | 3 |
| 63 | TABLE ACCESS FULL | VHD_CALLDESK_ARCHIVE | 1 | 1401 | 2 |
| 64 | VIEW PUSHED PREDICATE | | 1 | 20 | 1 |
|* 65 | FILTER | | | | |
| 66 | TABLE ACCESS BY INDEX ROWID | VHD_CALLDESK_HISTORY | 1 | 20 | 2 |
|* 67 | INDEX RANGE SCAN | VHD_CALLDSK_HIST_CALLID_IDX | 1 | | 1 |
|* 68 | FILTER | | | | |
| 69 | SORT GROUP BY NOSORT | | 1 | 12 | 2 |
| 70 | TABLE ACCESS BY INDEX ROWID| VHD_CALLDESK_HISTORY | 1 | 12 | 2 |
|* 71 | INDEX RANGE SCAN | VHD_CALLDSK_HIST_CALLID_IDX | 1 | | 1 |
| 72 | TABLE ACCESS BY INDEX ROWID | VHD_CALLMODE | 1 | 9 | 1 |
|* 73 | INDEX UNIQUE SCAN | VHD_CALLMOD_MODID_PK | 1 | | |
| 74 | TABLE ACCESS BY INDEX ROWID | VHD_APPLICATIONS | 1 | 20 | 1 |
|* 75 | INDEX UNIQUE SCAN | VHD_APPL_APPLID_PK | 1 | | |
| 76 | TABLE ACCESS BY INDEX ROWID | VHD_CALLTYPES | 1 | 21 | 1 |
|* 77 | INDEX UNIQUE SCAN | VHD_CALLTYP_ID_PK | 1 | | |
| 78 | TABLE ACCESS BY INDEX ROWID | VHD_TEAMS | 1 | 21 | 1 |
|* 79 | INDEX UNIQUE SCAN | VHD_TEAMID_PK | 1 | | |
| 80 | TABLE ACCESS BY INDEX ROWID | VHD_ENVIRONMENT | 1 | 21 | 1 |
|* 81 | INDEX UNIQUE SCAN | VHD_ENV_APLENVID_PK | 1 | | |
| 82 | TABLE ACCESS BY INDEX ROWID | VHD_MODULES | 1 | 22 | 1 |
|* 83 | INDEX UNIQUE SCAN | VHD_MOD_APLMOD_ID_PK | 1 | | |
| 84 | TABLE ACCESS BY INDEX ROWID | COM_RPTORGANIZATION | 1 | 14 | |
|* 85 | INDEX UNIQUE SCAN | COM_RPTORG_PK | 1 | | |
| 86 | TABLE ACCESS BY INDEX ROWID | COM_ORGANIZATION | 1 | 16 | |
|* 87 | INDEX UNIQUE SCAN | COM_ORG_PK | 1 | | |
| 88 | TABLE ACCESS BY INDEX ROWID | LCC_USERINFO_DETAILS | 1 | 43 |
|* 89 | INDEX UNIQUE SCAN | LCCUSERINFOIND | 1 | | |
| 90 | TABLE ACCESS BY INDEX ROWID | LCC_USERINFO_DETAILS | 1 | 24 |
|* 91 | INDEX UNIQUE SCAN | LCCUSERINFOIND | 1 | | |
| 92 | TABLE ACCESS BY INDEX ROWID | LCC_USERINFO_DETAILS | 1 | 24 | 1
|* 93 | INDEX UNIQUE SCAN | LCCUSERINFOIND | 1 | | |
| 94 | TABLE ACCESS BY INDEX ROWID | LCC_USERINFO_DETAILS | 1 | 24 | 1
|* 95 | INDEX UNIQUE SCAN | LCCUSERINFOIND | 1 | | |
Predicate Information (identified by operation id):
16 - filter("J"."TREE"='HLPDK')
18 - access("J"."ORGID"="A"."ORGID")
20 - filter( EXISTS (SELECT /*+ */ 0 FROM "LCC"."VHD_CALLDESK_HISTORY" "Q" WHERE "Q"."CALL_ID"=:B1
"Q"."CALL_ID" HAVING MIN("Q"."UPDDATE")=:B2))
22 - access("SYS_ALIAS_2"."CALL_ID"="A"."CALL_ID")
23 - filter(MIN("Q"."UPDDATE")=:B1)
26 - access("Q"."CALL_ID"=:B1)
28 - access("H"."MODE_ID"(+)="A"."MODE_ID")
30 - access("D"."APPL_ID"="A"."APPL_ID")
32 - access("F"."CALL_TYPE_ID"="A"."CALL_TYPE_ID")
34 - access("L"."TEAM_ID"(+)="A"."LAST_ACTION_TEAM")
36 - access("I"."APPL_ID"(+)="A"."APPL_ID" AND "I"."ENV_ID"(+)="A"."ENV_ID")
38 - access("E"."APPL_ID"="A"."APPL_ID" AND "E"."MODULE_ID"="A"."MODULE_ID")
40 - access("C"."CODE"="A"."ORGID")
42 - access("K"."USER_NAME"(+)="A"."LAST_ACTION_USER")
44 - access("B"."USER_NAME"(+)="A"."CALLER_ID")
46 - access("G"."USER_NAME"(+)="A"."UPDUSERID")
48 - access("LU"."USER_NAME"(+)=NVL("SYS_ALIAS_4"."UPDUSERID_162","SYS_ALIAS_4"."UPDUSERID_25"))
65 - filter( EXISTS (SELECT /*+ */ 0 FROM "LCC"."VHD_CALLDESK_HISTORY" "Q" WHERE "Q"."CALL_ID"=:B1
"Q"."CALL_ID" HAVING MIN("Q"."UPDDATE")=:B2))
67 - access("SYS_ALIAS_2"."CALL_ID"="SYS_ALIAS_1"."CALL_ID")
68 - filter(MIN("Q"."UPDDATE")=:B1)
71 - access("Q"."CALL_ID"=:B1)
73 - access("H"."MODE_ID"(+)="SYS_ALIAS_1"."MODE_ID")
75 - access("D"."APPL_ID"="SYS_ALIAS_1"."APPL_ID")
77 - access("F"."CALL_TYPE_ID"="SYS_ALIAS_1"."CALL_TYPE_ID")
79 - access("L"."TEAM_ID"(+)=TO_NUMBER("SYS_ALIAS_1"."LAST_ACTION_USER"))
81 - access("I"."APPL_ID"(+)="SYS_ALIAS_1"."APPL_ID" AND "I"."ENV_ID"(+)="SYS_ALIAS_1"."ENV_ID")
83 - access("E"."APPL_ID"="SYS_ALIAS_1"."APPL_ID" AND "E"."MODULE_ID"="SYS_ALIAS_1"."MODULE_ID")
85 - access("SYS_ALIAS_1"."ORGID"="J"."ORGID" AND "J"."TREE"='HLPDK')
87 - access("C"."CODE"="SYS_ALIAS_1"."ORGID")
89 - access("B"."USER_NAME"(+)="SYS_ALIAS_1"."CALLER_ID")
91 - access("SYS_ALIAS_1"."UPDUSERID"="G"."USER_NAME"(+))
93 - access("K"."USER_NAME"(+)="SYS_ALIAS_1"."LAST_ACTION_USER")
95 - access("LU"."USER_NAME"(+)=NVL("SYS_ALIAS_3"."UPDUSERID_162","SYS_ALIAS_3"."UPDUSERID_25"))
Note: cpu costing is offI've tried to look thru your sql and changed it a bit. Of course not testet :-)
Your problem isn't the archive table! I tried to remove the 2 selects from the select-clause. Furthermore you have a lot of nested loops in your explain, which is a performance-killer. Try getting rid of them, perhaps use /*+ USE_HASH(?,?) */.
SELECT a.call_id, a.entry_date,
NVL (INITCAP (b.full_name), caller_name) AS caller_name, c.description AS org_desc, a.env_id, i.env_desc, a.appl_id,
d.appl_desc, a.module_id, e.module_desc, a.call_type_id, f.call_type_desc, a.priority, a.upduserid,
INITCAP (g.full_name) AS lastupdated_username, a.call_desc, h.mode_desc, a.received_time, a.assignment_team, a.status,
ROUND (lcc.pkg_com.fn_datediff ('MI', a.entry_date, a.status_date)) AS elapsed_time,
ROUND (lcc.pkg_com.fn_datediff ('MI', a.entry_date, a.status_date)) AS resolved_min,
CASE
WHEN a.orgid IN (1, 100, 200)
THEN a.orgid
ELSE j.regionorgid
END AS region,
COALESCE (stat.upddate, a.upddate) AS stat_upddate,
t.team_desc, a.eta_date,
COALESCE (a.caller_contact, b.telephone) AS caller_contact,
COALESCE (a.caller_email, b.email) AS email, a.affected_users,
a.outage_time, a.qa_done, a.last_action_team, a.last_action_user,
INITCAP (k.full_name) AS last_action_username, a.last_action_date,
l.team_desc AS last_action_teamdesc, a.refid,
INITCAP (lu.full_name) AS logged_name, a.pmreview,
a.status AS main_status
FROM lcc.vhd_calldesk_archive a, lcc.lcc_userinfo_details b, lcc.com_organization c,
lcc.vhd_applications d, lcc.vhd_modules e, lcc.vhd_calltypes f, lcc.com_rptorganization j,
lcc.lcc_userinfo_details g, lcc.vhd_callmode h, lcc.vhd_environment i, lcc.lcc_userinfo_details k,
lcc.vhd_teams l,
(SELECT call_id, upduserid
FROM lcc.vhd_calldesk_history p
WHERE upddate IN (SELECT MIN (upddate)
FROM lcc.vhd_calldesk_history q
WHERE q.call_id = p.call_id
GROUP BY call_id)) ku,
lcc.lcc_userinfo_details lu,
(SELECT call_id, MAX (upddate)
FROM lcc.vhd_callstatus
GROUP BY call_id) stat,
lcc.vhd_teams t
WHERE a.caller_id = b.user_name(+)
AND a.orgid = c.code
AND a.appl_id = d.appl_id
AND a.appl_id = e.appl_id
AND a.module_id = e.module_id
AND a.call_type_id = f.call_type_id
AND a.orgid = j.orgid
AND j.tree = 'HLPDK'
AND a.upduserid = g.user_name(+)
AND a.mode_id = h.mode_id(+)
AND a.appl_id = i.appl_id(+)
AND a.env_id = i.env_id(+)
AND a.last_action_user = k.user_name(+)
AND a.last_action_user = l.team_id(+)
AND a.call_id = ku.call_id(+)
AND NVL (ku.upduserid, a.upduserid) = lu.user_name(+)
AND a.call_id = stat.call_id
AND a.assignment_team = t.team_id;
Maybe you are looking for
-
Oracle doesn't start with startsap
Hi, Today we updated the oracle database from 10.2.0.2 to 10.2.0.4 and then we applied the 7592346 CPU, we have a Portal 7.0 with HPUX, when we try to start the database with startsap we saw an error and we cant start the database: 4 ETW000
-
Is it safe to enable "write changes into XMP"?
I am evaluating the LR4 beta using my existing tree of master photos. (Have to put the thing under a realistic load, or there is no test.) If I make a change to a photo with XMP writing enabled in the catalog settings, will LR3 be able to cope with t
-
Re-activating old iPhone won't work?
I stopped using my iPhone around January of this year, and now I'm trying to switch back. I restored it to the factory settings and now am trying to activate it again, but it won't prompt the activation screen in iTunes. The phone is still on the sam
-
Safari not displaying pages correctly after upgrade to Mavericks
Hi, I just upgraded my macbook pro (mid 2010) to Mavericks and safari now displays web pages as if I was really zoomed in. When I load a page I will see it correctly for a second and it will then zoom in (no amount of pinch on my trackpad solves the
-
I am writting an application that can be used to access and edit a database. I have already written the servlet using Oracle JDeveloper. I have compiled the servlet and put the resulting class file under the following directories: - [tomcat]\webapps\