Hash unique performance.
Hi,
We are running 10.2.0.3.0 on Aix 5.3. We are seeing massive performance degredation with statements resolved by hash unique.
A statement of the type
update tab set col =
(select distinct col
from othertab
where othertab.joincol = tab.joincol)
will be resolved using a hash unique at the distinct point and will run very, very slowly.
if we change the statement to two statements...
insert into temptab
(select distinct joincol, col
from othertab);
update tab
set col = (select col from temptab where temptab.joincol = tab.joincol)
Then performance will be exponentially quicker even though the insert will still do a hash unique.
We have opened an SR, we have tried coding round the hash unique using group by, we have checked the hashing is not being done on disk, we have checked for swapping, we have set the work_area_size policy to manual and provided 1GB of physical memory for the session - only a fraction got used and the statement ran slowly.
Any one any suggestions?
We just upgraded from 9.2.0.2 to 10.2.0.3... and also experienced the same massive performance change. Updates in 9i taking 1-3 hours were showing 20-60 hours per the long run (OEM). We also noted our 4 and 8 cpu boxes hitting or staying very near 100% utilization. IO has been our main concern on this project, never cpu.
The explain plan between 9i and 10G for all the update statements effected were the identiical with one exception... in 9i there was a SORT UNIQUE where as in 10G it was replaced with a HASH UNIQUE.
We also found the same URL referenced above... setting this undocumented init parameter _gby_hash_aggregation_enabled to false resulted in the SORT UNIQUE to return and now the scripts are running even faster in 10G then in 9i now - about 1/3 faster.
Note, our 9i used 8K block size… 10G is using 16K. Our tables have 10 of millions of records loaded every day so this was a critical issue for our project.
Dave C
Similar Messages
-
Why UNION would not use hash unique
When issue a query like 'select distinct ....'
it will use hash unique instead of sort unique on oracle database version 10gr2 or higher.
Is it possible that UNION operations use a hash unique to eliminate duplicate rows?
Thanks.NathanielNie wrote:
When issue a query like 'select distinct ....'
it will use hash unique instead of sort unique on oracle database version 10gr2 or higher.
Is it possible that UNION operations use a hash unique to eliminate duplicate rows?
Thanks.are you applying for a job to improve the CBO's behavior? -
I have a performance issue with a query - it would be something like -
select col1,col2, sum(col3), get_val(col_4)
from table1
where
get_val(col_4) is not null
group by col1,col2, get_val(col_4)
I have simplified this but it is something similar. This works great - performance is great. Now I commented out the where clause as I needed to populate null values - and that's it the query does not retrieve the resultset - it keeps running forever. With the where clause it comes back in 60 seconds. There is only one row out of 560 rows that has null value for col_4 which i need to display.
Any help is appreciated.The only difference I notice between the two sqls is HASH(UNIQUE) -
with IS NOT NULL in where clause -
SELECT STATEMENT ALL_ROWS 1598 1 209
HASH(UNIQUE) 1598 1 209
HASH(GROUP BY) 1598 1 209
When is not null is removed from the where clause -
SELECT STATEMENT ALL_ROWS 1598 1 206
HASH(GROUP BY) 1598 1 206
I'm guessing that the index is being used in the first scenario and not in the second. Any idea/suggestion as to how to over come this?
Thanks -
Query Performance Tuning - Help
Hello Experts,
Good Day to all...
TEST@ora10g>select * from v$version;
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
PL/SQL Release 10.2.0.4.0 - Production
"CORE 10.2.0.4.0 Production"
TNS for IBM/AIX RISC System/6000: Version 10.2.0.4.0 - Productio
NLSRTL Version 10.2.0.4.0 - Production
SELECT fa.user_id,
fa.notation_type,
MAX(fa.created_date) maxDate,
COUNT(*) bk_count
FROM book_notations fa
WHERE fa.user_id IN
( SELECT user_id
FROM
( SELECT /*+ INDEX(f2,FBK_AN_ID_IDX) */ f2.user_id,
MAX(f2.notatn_id) f2_annotation_id
FROM book_notations f2,
title_relation tdpr
WHERE f2.user_id IN ('100002616221644',
'100002616221645',
'100002616221646',
'100002616221647',
'100002616221648')
AND f2.pack_id=tdpr.pack_id
AND tdpr.title_id =93402
GROUP BY f2.user_id
ORDER BY 2 DESC)
WHERE ROWNUM <= 10)
GROUP BY fa.user_id,
fa.notation_type
ORDER BY 3 DESC;Cost of the Query is too much...
Below is the explain plan of the query
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 29 | 1305 | 52 (10)| 00:00:01 |
| 1 | SORT ORDER BY | | 29 | 1305 | 52 (10)| 00:00:01 |
| 2 | HASH GROUP BY | | 29 | 1305 | 52 (10)| 00:00:01 |
| 3 | TABLE ACCESS BY INDEX ROWID | book_notations | 11 | 319 | 4 (0)| 00:00:01 |
| 4 | NESTED LOOPS | | 53 | 2385 | 50 (6)| 00:00:01 |
| 5 | VIEW | VW_NSO_1 | 5 | 80 | 29 (7)| 00:00:01 |
| 6 | HASH UNIQUE | | 5 | 80 | | |
|* 7 | COUNT STOPKEY | | | | | |
| 8 | VIEW | | 5 | 80 | 29 (7)| 00:00:01 |
|* 9 | SORT ORDER BY STOPKEY | | 5 | 180 | 29 (7)| 00:00:01 |
| 10 | HASH GROUP BY | | 5 | 180 | 29 (7)| 00:00:01 |
| 11 | TABLE ACCESS BY INDEX ROWID | book_notations | 5356 | 135K| 26 (0)| 00:00:01 |
| 12 | NESTED LOOPS | | 6917 | 243K| 27 (0)| 00:00:01 |
| 13 | MAT_VIEW ACCESS BY INDEX ROWID| title_relation | 1 | 10 | 1 (0)| 00:00:01 |
|* 14 | INDEX RANGE SCAN | IDX_TITLE_ID | 1 | | 1 (0)| 00:00:01 |
| 15 | INLIST ITERATOR | | | | | |
|* 16 | INDEX RANGE SCAN | FBK_AN_ID_IDX | 5356 | | 4 (0)| 00:00:01 |
|* 17 | INDEX RANGE SCAN | FBK_AN_ID_IDX | 746 | | 1 (0)| 00:00:01 |
Table Details
SELECT COUNT(*) FROM book_notations; --111367
Columns
user_id -- nullable field - VARCHAR2(50 BYTE)
pack_id -- NOT NULL --NUMBER
notation_type-- VARCHAR2(50 BYTE) -- nullable field
CREATED_DATE - DATE -- nullable field
notatn_id - VARCHAR2(50 BYTE) -- nullable field
Index
FBK_AN_ID_IDX - Non unique - Composite columns --> (user_id and pack_id)
SELECT COUNT(*) FROM title_relation; --12678
Columns
pack_id - not null - number(38) - PK
title_id - not null - number(38)
Index
IDX_TITLE_ID - Non Unique - TITLE_ID
Please help...
Thanks...Linus wrote:
Thanks Bravid for your reply; highly appreciate that.
So as you say; index creation on the NULL column doesnt have any impact. OK fine.
What happens to the execution plan, performance and the stats when you remove the index hint?
Find below the Execution Plan and Predicate information
"PLAN_TABLE_OUTPUT"
"Plan hash value: 126058086"
"| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |"
"| 0 | SELECT STATEMENT | | 25 | 1125 | 55 (11)| 00:00:01 |"
"| 1 | SORT ORDER BY | | 25 | 1125 | 55 (11)| 00:00:01 |"
"| 2 | HASH GROUP BY | | 25 | 1125 | 55 (11)| 00:00:01 |"
"| 3 | TABLE ACCESS BY INDEX ROWID | book_notations | 10 | 290 | 4 (0)| 00:00:01 |"
"| 4 | NESTED LOOPS | | 50 | 2250 | 53 (8)| 00:00:01 |"
"| 5 | VIEW | VW_NSO_1 | 5 | 80 | 32 (10)| 00:00:01 |"
"| 6 | HASH UNIQUE | | 5 | 80 | | |"
"|* 7 | COUNT STOPKEY | | | | | |"
"| 8 | VIEW | | 5 | 80 | 32 (10)| 00:00:01 |"
"|* 9 | SORT ORDER BY STOPKEY | | 5 | 180 | 32 (10)| 00:00:01 |"
"| 10 | HASH GROUP BY | | 5 | 180 | 32 (10)| 00:00:01 |"
"| 11 | TABLE ACCESS BY INDEX ROWID | book_notations | 5875 | 149K| 28 (0)| 00:00:01 |"
"| 12 | NESTED LOOPS | | 7587 | 266K| 29 (0)| 00:00:01 |"
"| 13 | MAT_VIEW ACCESS BY INDEX ROWID| title_relation | 1 | 10 | 1 (0)| 00:00:01 |"
"|* 14 | INDEX RANGE SCAN | IDX_TITLE_ID | 1 | | 1 (0)| 00:00:01 |"
"| 15 | INLIST ITERATOR | | | | | |"
"|* 16 | INDEX RANGE SCAN | FBK_AN_ID_IDX | 5875 | | 4 (0)| 00:00:01 |"
"|* 17 | INDEX RANGE SCAN | FBK_AN_ID_IDX | 775 | | 1 (0)| 00:00:01 |"
"Predicate Information (identified by operation id):"
" 7 - filter(ROWNUM<=10)"
" 9 - filter(ROWNUM<=10)"
" 14 - access(""TDPR"".""TITLE_ID""=93402)"
" 16 - access((""F2"".""USER_ID""='100002616221644' OR ""F2"".""USER_ID""='100002616221645' OR "
" ""F2"".""USER_ID""='100002616221646' OR ""F2"".""USER_ID""='100002616221647' OR "
" ""F2"".""USER_ID""='100002616221648') AND ""F2"".""PACK_ID""=""TDPR"".""PACK_ID"")"
" 17 - access(""FA"".""USER_ID""=""$nso_col_1"")"
The cost is the same because the plan is the same. The optimiser chose to use that index anyway. The point is, now that you have removed it, the optimiser is free to choose other indexes or a full table scan if it wants to.
>
Statistics
BEGIN
DBMS_STATS.GATHER_TABLE_STATS ('TEST', 'BOOK_NOTATIONS');
END;
"COLUMN_NAME" "NUM_DISTINCT" "NUM_BUCKETS" "HISTOGRAM"
"NOTATION_ID" 110269 1 "NONE"
"USER_ID" 213 212 "FREQUENCY"
"PACK_ID" 20 20 "FREQUENCY"
"NOTATION_TYPE" 8 8 "FREQUENCY"
"CREATED_DATE" 87 87 "FREQUENCY"
"CREATED_BY" 1 1 "NONE"
"UPDATED_DATE" 2 1 "NONE"
"UPDATED_BY" 2 1 "NONE"
After removing the hint ; the query still shows the same "COST"
Autotrace
recursive calls 1
db block gets 0
consistent gets 34706
physical reads 0
redo size 0
bytes sent via SQL*Net to client 964
bytes received via SQL*Net from client 1638
SQL*Net roundtrips to/from client 2
sorts (memory) 3
sorts (disk) 0
Output of query
"USER_ID" "NOTATION_TYPE" "MAXDATE" "COUNT"
"100002616221647" "WTF" 08-SEP-11 20000
"100002616221645" "LOL" 08-SEP-11 20000
"100002616221644" "OMG" 08-SEP-11 20000
"100002616221648" "ABC" 08-SEP-11 20000
"100002616221646" "MEH" 08-SEP-11 20000Thanks...I still don't know what we're working towards at the moment. WHat is the current run time? What is the expected run time?
I can't tell you if there's a better way to write this query or if indeed there is another way to write this query because I don't know what it is attempting to achieve.
I can see that you're accessing 100k rows from a 110k row table and it's using an index to look those rows up. That seems like a job for a full table scan rather than index lookups.
David -
Oracle 11g performance issue ( BITMAP CONVERSION TO ROWIDS)
I have two instance of oracle 11g.
in both instance i fired same query.
one instance returns the result in 1sec but other instance returns the result in 10 sec
following is explain plan for bot instance
instance 1
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 143 | 59 (2)| 00:00:01 |
| 1 | HASH GROUP BY | | 1 | 143 | 59 (2)| 00:00:01 |
| 2 | VIEW | VM_NWVW_2 | 1 | 143 | 59 (2)| 00:00:01 |
| 3 | HASH UNIQUE | | 1 | 239 | 59 (2)| 00:00:01 |
| 4 | NESTED LOOPS | | | | | |
| 5 | NESTED LOOPS | | 1 | 239 | 58 (0)| 00:00:01 |
PLAN_TABLE_OUTPUT
| 6 | NESTED LOOPS | | 1 | 221 | 57 (0)| 00:00:01 |
| 7 | NESTED LOOPS | | 1 | 210 | 55 (0)| 00:00:01 |
| 8 | NESTED LOOPS | | 1 | 184 | 54 (0)| 00:00:01 |
| 9 | NESTED LOOPS | | 1 | 158 | 53 (0)| 00:00:01 |
| 10 | NESTED LOOPS | | 1 | 139 | 52 (0)| 00:00:01 |
| 11 | NESTED LOOPS | | 1 | 105 | 50 (0)| 00:00:01 |
|* 12 | INDEX RANGE SCAN | year_field | 1 | 29 | 2 (0)| 00:00:01 |
| 13 | SORT AGGREGATE | | 1 | 8 | | |
| 14 | INDEX FULL SCAN (MIN/MAX)| idx_bf_creation_date | 1 | 8 | 2 (0)| 00:00:01 |
|* 15 | TABLE ACCESS BY INDEX ROWID| OHRT_bugs_fact | 1 | 76 | 48 (0)| 00:00:01 |
|* 16 | INDEX RANGE SCAN | idx_bf_creation_date | 76 | | 1 (0)| 00:00:01 |
PLAN_TABLE_OUTPUT
|* 17 | TABLE ACCESS BY INDEX ROWID | OHRT_all_time_dimension | 1 | 34 | 2 (0)| 00:00:01 |
|* 18 | INDEX UNIQUE SCAN | unique_alltime_bug_instance_id | 1 | | 1 (0)| 00:00:01 |
| 19 | TABLE ACCESS BY INDEX ROWID | OHRT_all_time_dimension | 1 | 19 | 1 (0)| 00:00:01 |
|* 20 | INDEX UNIQUE SCAN | unique_alltime_bug_instance_id | 1 | | 1 (0)| 00:00:01 |
|* 21 | INDEX RANGE SCAN | bugseverity_instance_id_ref_id | 1 | 26 | 1 (0)| 00:00:01 |
|* 22 | INDEX UNIQUE SCAN | unique_alltime_bug_instance_id | 1 | 26 | 1 (0)| 00:00:01 |
| 23 | INLIST ITERATOR | | | | | |
|* 24 | TABLE ACCESS BY INDEX ROWID | OHMT_ANL_BUCKET | 1 | 11 | 2 (0)| 00:00:01 |
|* 25 | INDEX UNIQUE SCAN | SYS_C0053213 | 5 | | 1 (0)| 00:00:01 |
|* 26 | INDEX RANGE SCAN | FK_BUCKET_TYPE | 6 | | 0 (0)| 00:00:01 |
|* 27 | TABLE ACCESS BY INDEX ROWID | OHMT_ANL_BUCKET | 1 | 18 | 1 (0)| 00:00:01 |
instance 2
Plan
SELECT STATEMENT ALL_ROWS Cost: 22 Bytes: 142 Cardinality: 1
32 HASH GROUP BY Cost: 22 Bytes: 142 Cardinality: 1
31 VIEW VIEW SYS.VM_NWVW_2 Cost: 22 Bytes: 142 Cardinality: 1
30 HASH UNIQUE Cost: 22 Bytes: 237 Cardinality: 1
29 NESTED LOOPS
27 NESTED LOOPS Cost: 21 Bytes: 237 Cardinality: 1
25 NESTED LOOPS Cost: 20 Bytes: 219 Cardinality: 1
21 NESTED LOOPS Cost: 18 Bytes: 208 Cardinality: 1
19 NESTED LOOPS Cost: 17 Bytes: 183 Cardinality: 1
17 NESTED LOOPS Cost: 16 Bytes: 157 Cardinality: 1
14 NESTED LOOPS Cost: 15 Bytes: 138 Cardinality: 1
11 NESTED LOOPS Cost: 13 Bytes: 104 Cardinality: 1
3 INDEX RANGE SCAN INDEX REPORTSDB.year_field Cost: 2 Bytes: 29 Cardinality: 1
2 SORT AGGREGATE Bytes: 8 Cardinality: 1
1 INDEX FULL SCAN (MIN/MAX) INDEX REPORTSDB.idx_bf_creation_date Cost: 3 Bytes: 8 Cardinality: 1
10 TABLE ACCESS BY INDEX ROWID TABLE REPORTSDB.OHRT_bugs_fact Cost: 13 Bytes: 75 Cardinality: 1
9 BITMAP CONVERSION TO ROWIDS
8 BITMAP AND
5 BITMAP CONVERSION FROM ROWIDS
4 INDEX RANGE SCAN INDEX REPORTSDB.idx_OHRT_bugs_fact_2product Cost: 2 Cardinality: 85
7 BITMAP CONVERSION FROM ROWIDS
6 INDEX RANGE SCAN INDEX REPORTSDB.idx_bf_creation_date Cost: 2 Cardinality: 85
13 TABLE ACCESS BY INDEX ROWID TABLE REPORTSDB.OHRT_all_time_dimension Cost: 2 Bytes: 34 Cardinality: 1
12 INDEX UNIQUE SCAN INDEX (UNIQUE) REPORTSDB.unique_alltime_bug_instance_id Cost: 1 Cardinality: 1
16 TABLE ACCESS BY INDEX ROWID TABLE REPORTSDB.OHRT_all_time_dimension Cost: 1 Bytes: 19 Cardinality: 1
15 INDEX UNIQUE SCAN INDEX (UNIQUE) REPORTSDB.unique_alltime_bug_instance_id Cost: 1 Cardinality: 1
18 INDEX UNIQUE SCAN INDEX (UNIQUE) REPORTSDB.unique_alltime_bug_instance_id Cost: 1 Bytes: 26 Cardinality: 1
20 INDEX RANGE SCAN INDEX REPORTSDB.bugseverity_instance_id_ref_id Cost: 1 Bytes: 25 Cardinality: 1
24 INLIST ITERATOR
23 TABLE ACCESS BY INDEX ROWID TABLE OPSHUB.OHMT_ANL_BUCKET Cost: 2 Bytes: 11 Cardinality: 1
22 INDEX UNIQUE SCAN INDEX (UNIQUE) OPSHUB.SYS_C0040939 Cost: 1 Cardinality: 5
26 INDEX RANGE SCAN INDEX OPSHUB.FK_BUCKET_TYPE Cost: 0 Cardinality: 6
28 TABLE ACCESS BY INDEX ROWID TABLE OPSHUB.OHMT_ANL_BUCKET Cost: 1 Bytes: 18 Cardinality: 1
in both explain plan only difference is
9 BITMAP CONVERSION TO ROWIDS
8 BITMAP AND
5 BITMAP CONVERSION FROM ROWIDS
but is bitmap degrading performance lot?
or suggest me what other parameter i can see so 2nd instance gives me better performace.I see more differences.
In plan 1:
* 16 INDEX RANGE SCAN idx_bf_creation_date 76 1 (0) 00:00:01
in Plan 2:
1 INDEX FULL SCAN (MIN/MAX) INDEX REPORTSDB.idx_bf_creation_date Cost: 3 Bytes: 8 Cardinality: 1
So this is not about "bitmap" good/bad, it about the access strategy which changed due to differences in data statistics etc. To analyze more, I'd help a LOT if those plans would be formated in a good and same way, use around it to do so. -
Hello Experts,
Please help me how the table "digital_compatibility" be modified for faster performance?
BANNER
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bi
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for IBM/AIX RISC System/6000: Version 10.2.0.1.0 - Productio
NLSRTL Version 10.2.0.1.0 - Production
Count of records for the tables:-
SELECT count(*) FROM DEVICE_TYPE; --421
SELECT count(*) FROM DIGITAL_COMPATIBILITY; --227757
CREATE TABLE DEVICE_TYPE
DEVICE_TYPE_ID NUMBER(38,0),
DEVICE_TYPE_MAKE VARCHAR2(256 BYTE),
DEVICE_TYPE_MODEL VARCHAR2(256 BYTE),
DEVICE_DISPLAY_NAME VARCHAR2(256 BYTE),
PARTNER_DEVICE_TYPE VARCHAR2(256 BYTE),
DEVICE_IMAGE_URL VARCHAR2(256 BYTE),
FOH_BUTTON_NAME VARCHAR2(256 BYTE),
FOH_ACTIVE_FLAG CHAR(1 BYTE),
BB_RETAIL_FLAG CHAR(1 BYTE),
DISPLAY_DESCRIPTION VARCHAR2(256 BYTE),
DEVICE_CATEGORY_ID NUMBER(38,0),
DEVICE_SUB_CATEGORY_ID NUMBER(38,0),
DEVICE_BRAND_ID NUMBER(38,0),
PARENT_ID NUMBER(38,0),
POWERED_BY VARCHAR2(256 BYTE),
CARRIER VARCHAR2(256 BYTE),
CAPABILITY_SET_ID NUMBER(38,0),
CREATED_BY VARCHAR2(32 BYTE),
CREATED_DATE DATE,
UPDATED_BY VARCHAR2(32 BYTE),
UPDATED_DATE DATE,
POWERED_BY_DEVICE_TYPE VARCHAR2(64 BYTE),
OPERATING_SYSTEM VARCHAR2(32 BYTE),
OPERATING_SYSTEM_VERSION VARCHAR2(32 BYTE),
BROWSER VARCHAR2(32 BYTE),
BROWSER_VERSION VARCHAR2(32 BYTE),
CLASSIFICATION VARCHAR2(32 BYTE),
CONSTRAINT PK_DEVICE_TYPE PRIMARY KEY ( DEVICE_TYPE_ID));
CREATE INDEX DEVICE_TYPE_IDX ON DEVICE_TYPE
CAPABILITY_SET_ID ,
UPPER( PARTNER_DEVICE_TYPE )
CREATE TABLE DIGITAL_COMPATIBILITY
DIGITAL_COMPATIBILITY_ID NUMBER NOT NULL ENABLE,
CAPABILITY_SET_ID NUMBER,
OBJECT_TYPE VARCHAR2(38 BYTE) NOT NULL ENABLE,
CREATED_DATE DATE NOT NULL ENABLE,
CREATED_BY VARCHAR2(38 BYTE) NOT NULL ENABLE,
UPDATED_DATE DATE NOT NULL ENABLE,
UPDATED_BY VARCHAR2(38 BYTE) NOT NULL ENABLE,
OBJECT_ID VARCHAR2(114 BYTE),
ENCODE_PROFILE_ID NUMBER
CREATE INDEX ENCODE_PROFILE_ID_IDX ON DIGITAL_COMPATIBILITY
ENCODE_PROFILE_ID,
OBJECT_ID,
OBJECT_TYPE
Query
=====
EXPLAIN PLAN FOR
SELECT /*+ INDEX(dc, ENCODE_PROFILE_ID_IDX) */
DISTINCT dc.object_id AS title_id
FROM digital_compatibility dc,
device_type dt
WHERE dc.capability_set_id = dt.capability_set_id
AND upper(dt.partner_device_type) = :1
AND dc.object_id IN (:2, :3, :4, :5, :6, :7, :8, :9, :10, :11, :12, :13, :14, :15, :16, :17, :18, :19, :20, :21, :22, :23, :24, :25, :26, :27, :28, :29, :30, :31, :32, :33)
AND dc.object_type =:"SYS_B_0";
Explain plan
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
| 0 | SELECT STATEMENT | | 2 | 472 | 274 (4)|
| 1 | HASH UNIQUE | | 2 | 472 | 274 (4)|
|* 2 | MAT_VIEW ACCESS BY INDEX ROWID| DIGITAL_COMPATIBILITY | 1 | 93 | 68 (3)|
| 3 | NESTED LOOPS | | 2 | 472 | 273 (4)|
|* 4 | INDEX FULL SCAN | DEVICE_TYPE_IDX | 4 | 572 | 1 (0)|
|* 5 | INDEX FULL SCAN | ENCODE_PROFILE_ID_IDX | 8 | | 67 (3)|
Predicate Information (identified by operation id):
2 - filter("DC"."CAPABILITY_SET_ID"="DT"."CAPABILITY_SET_ID")
4 - access(UPPER("PARTNER_DEVICE_TYPE")=:1)
filter(UPPER("PARTNER_DEVICE_TYPE")=:1)
5 - access("DC"."OBJECT_TYPE"=:SYS_B_0)
filter(("DC"."OBJECT_ID"=:2 OR "DC"."OBJECT_ID"=:3 OR "DC"."OBJECT_ID"=:4 OR
"DC"."OBJECT_ID"=:5 OR "DC"."OBJECT_ID"=:6 OR "DC"."OBJECT_ID"=:7 OR
"DC"."OBJECT_ID"=:8 OR "DC"."OBJECT_ID"=:9 OR "DC"."OBJECT_ID"=:10 OR
"DC"."OBJECT_ID"=:11 OR "DC"."OBJECT_ID"=:12 OR "DC"."OBJECT_ID"=:13 OR
"DC"."OBJECT_ID"=:14 OR "DC"."OBJECT_ID"=:15 OR "DC"."OBJECT_ID"=:16 OR
"DC"."OBJECT_ID"=:17 OR "DC"."OBJECT_ID"=:18 OR "DC"."OBJECT_ID"=:19 OR
"DC"."OBJECT_ID"=:20 OR "DC"."OBJECT_ID"=:21 OR "DC"."OBJECT_ID"=:22 OR
"DC"."OBJECT_ID"=:23 OR "DC"."OBJECT_ID"=:24 OR "DC"."OBJECT_ID"=:25 OR
"DC"."OBJECT_ID"=:26 OR "DC"."OBJECT_ID"=:27 OR "DC"."OBJECT_ID"=:28 OR
"DC"."OBJECT_ID"=:29 OR "DC"."OBJECT_ID"=:30 OR "DC"."OBJECT_ID"=:31 OR
"DC"."OBJECT_ID"=:32 OR "DC"."OBJECT_ID"=:33) AND "DC"."OBJECT_TYPE"=:SYS_B_0)
Note
- 'PLAN_TABLE' is old version
Trace
recursive calls 280
db block gets 16
consistent gets 97
physical reads 0
redo size 3224
bytes sent via SQL*Net to client 589
bytes received via SQL*Net from client 1598
SQL*Net roundtrips to/from client 2
sorts (memory) 4
sorts (disk) 0
Thanks ....You index on DIGITAL_COMPATIBILITY is on ENCODE_PROFILE_ID, OBJECT_ID, OBJECT_TYPE
But you query for object_id and object_type.
How much rows you you identify with this? What the PK?
The way it's now, it needs to read the full index, then the table and as DEVICE_TYPE is small it makes a NL to it.
Makes sense.
If you would add an index on OBJECT_ID, OBJECT_TYPE and capability_set_id ORACLE would just need to read the INDEX. -
Adding indexes to a table is slowing down query performance.
I am running a query against a table which contains approx. 4 million records in it. So I created 4 indexes on the table and noticed that the performance on my query drastically decreased. I went back and began remove and creating the indexes in different combinations. It turns out that whenever two of four indexes are created the performance worsens. The strange thing about this problem is when I do an explain plan on the query the cost is greater when the performance is better and the cost is less when the performance is worse. Also Oracle only uses one out of the four indexes on the table for this query.
I'd like to try to understand what is going on with the Oracle optimizer to try to fix this problem.Mark,
Below is the information you requested.
DATABASE: 10.2.0.3.0
QUERY:
select distinct object, object_access from betweb_objects
where instr(object_access,'RES\') = 0
and object_access_type = 'ADM'
and object in (select distinct object
from betweb_objects
where instr(object_access,'RES\') = 0
and object_access_type = 'NTK'
and object not like '%.%'
and substr(object_access,instr(object_access,'\')+1) in (select distinct substr(object_access,instr(object_access,'\')+1)
from betweb_objects
where object_access_type = 'NTK'
and instr(object_access,'RES\') = 0
minus
select distinct upper(id)
from uamp.ad_users
where status = 'A'))
TABLE:
BETWEB_OBJECTS
OBJECT VARCHAR2
OBJECT_ACCESS VARCHAR2
OBJECT_ACCESS_TYPE VARCHAR2
INDEXES ON BETWEB_OBJECTS:
BETWEB_OBJECTS_IDX1
OBJECT
BETWEB_OBJECTS_IDX2
OBJECT_ACCESS
BETWEB_OBJECTS_IDX3
OBJECT_ACCESS_TYPE
BETWEB_OBJECTS_IDX4
OBJECT_ACCESS
OBJECT_ACCESS_TYPE
TABLE:
AD_USERS
ID VARCHAR2
DOMAIN VARCHAR2
FNAME VARCHAR2
LNAME VARCHAR2
INITIALS VARCHAR2
TITLE VARCHAR2
DN VARCHAR2
COMPANY VARCHAR2
DEPARTMENT VARCHAR2
PHONE VARCHAR2
MANAGER VARCHAR2
STATUS VARCHAR2
DISPLAY_NAME VARCHAR2
EXPLAIN PLAN when performance is better:
SELECT STATEMENT Rows=13,414 Time=643,641 Cost=53,636,676 Bytes=6,948,452
HASH UNIQUE Rows=13,414 Time=643,641 Cost=53,636,676 Bytes=6,948,452
HASH JOIN Rows=694,646,835 Time=428 Cost=35,620 Bytes=359,827,060,530
VIEW VW_NSO_1 Rows=542 Time=42 Cost=3,491 Bytes=163,684
MINUS
SORT UNIQUE Rows=542 Bytes=9,756
INDEX FAST FULL SCAN BETWEB_OBJECTS_IDX4 Rows=26,427 Time=40 Cost=3,302 Bytes=475,686
SORT UNIQUE Rows=16,228 Bytes=178,508
TABLE ACCESS FULL AD_USERS Rows=16,360 Time=2 Cost=113 Bytes=179,960
HASH JOIN Rows=128,163,623 Time=322 Cost=26,805 Bytes=27,683,342,568
TABLE ACCESS FULL BETWEB_OBJECTS Rows=9,161 Time=154 Cost=12,805 Bytes=989,388
TABLE ACCESS FULL BETWEB_OBJECTS Rows=25,106 Time=154 Cost=12,822 Bytes=2,711,448
EXPLAIN PLAN when performance is worse:
SELECT STATEMENT Rows=13,414 Time=22,614 Cost=1,884,484 Bytes=2,897,424
HASH UNIQUE Rows=13,414 Time=22,614 Cost=1,884,484 Bytes=2,897,424
HASH JOIN Rows=128,163,623 Time=322 Cost=26,805 Bytes=27,683,342,568
TABLE ACCESS FULL BETWEB_OBJECTS Rows=9,161 Time=154 Cost=12,805 Bytes=989,388
TABLE ACCESS FULL BETWEB_OBJECTS Rows=25,106 Time=154 Cost=12,822 Bytes=2,711,448
MINUS
SORT UNIQUE NOSORT Rows=209 Time=40 Cost=3,305 Bytes=3,762
INDEX FAST FULL SCAN BETWEB_OBJECTS_IDX4 Rows=264 Time=40 Cost=3,304 Bytes=4,752
SORT UNIQUE NOSORT Rows=164 Time=2 Cost=115 Bytes=1,804
TABLE ACCESS FULL AD_USERS Rows=164 Time=2 Cost=114 Bytes=1,804 -
HI Experts
One of our developers is facing performance issue on one query using dblinks.
When we run the query in remote db it is taking 4-5 mins.
When we execute the query from his local db using db links it is never ending.
Looking at this initially we are suspecting to be network issue.
we did some testing and found
Scenario 1
When we execute the query from his local db which is using some of his local tables and some remote tables it never ends.
We did session tracing and found that it waiting on
WAIT #1: nam='SQL*Net message from dblink' ela= 43367 driver id=675562835 #bytes=1 p3=0 obj#=-1 tim=10635854911875
WAIT #1: nam='SQL*Net message to dblink' ela= 1 driver id=675562835 #bytes=1 p3=0 obj#=-1 tim=10635854911949
WAIT #1: nam='SQL*Net message from dblink' ela= 42156 driver id=675562835 #bytes=1 p3=0 obj#=-1 tim=10635854954117
WAIT #1: nam='SQL*Net message to dblink' ela= 0 driver id=675562835 #bytes=1 p3=0 obj#=-1 tim=10635854954193
Scenario 2
When we execute the query from his local db using all the tables in the remote db using dblinks it is executing in 6-7 mins.
Problem is occuring when we use some of the tables in his local schema and some table in his remote db schema .
Tables that exist in his local schema are very small.
At this stage we are not sure whether this could be due to network or some other issue.
Any Ideas?
Thanks in Advance.
MehtabYou didn't post a 4 digit database version local 10.2.0.3 remote is 9.2.0.7
- You didn't post a version
- You didn't post the actual statement
SELECT /*+DRIVING_SITE( )*/ DISTINCT dsnh.notif_nr
,dsnh.sales_org_id
,dsnh.sales_org_name
,dsnh.fiscal_year
,dsnh.fiscal_period
,dsnh.fiscal_week_period
,dsnh.notif_type
,dsnh.notif_type_desc
,dsnh.repair_scenario
,dsnh.product_class_code
,dsnh.shipto_partner_nr
,dsnh.sales_channel
,dsnh.channel_type233 characters
,dsnh.header_warranty_code
,dsnh.depot_partner_name
,dsnh.shipto_partner_name
FROM dn_service_notification_hdr@dblink dsnh,
sap_customer@dblink sc,
sys_statuses@dblink systbl,
external_internal_tbl@dblink exttbl
WHERE dsnh.shipto_partner_nr = sc.sap_cust_no
AND dsnh.notif_nr = systbl.doc_nr
AND systbl.sys_status = exttbl.ext_status
AND UPPER(dsnh.notif_type)
IN (SELECT UPPER(notif_type)
FROM opc_notif_type_1
WHERE report_name = 'NEW REPAIR VOLUME'
AND service_description = 'Carry In'
AND UPPER(dsnh.notif_type)||' - '||UPPER(exttbl.ext_status)
NOT IN (SELECT UPPER(notif_type)||' - '||UPPER(cancel_flag_value)
FROM opc_notif_type_1
WHERE report_name = 'NEW REPAIR VOLUME'
AND service_description = 'Carry In'
AND dsnh.repair_scenario IN (SELECT repair_scenario
FROM opc_repair_scenario_1
WHERE report_name = 'NEW REPAIR VOLUME'
AND service_description = 'Carry In'
AND UPPER(sc.sales_district) IN (SELECT UPPER(sales_district)
FROM opc_sales_district_1
WHERE report_name = 'NEW REPAIR VOLUME'
AND service_description = 'Carry In'
AND dsnh.sales_org_id IN (SELECT sales_org_id
FROM opc_sales_org_1 )
AND dsnh.header_warranty_code <>'OO'
AND TO_DATE(TO_CHAR(dsnh.notification_creation_dt,'MM/DD/RRRR'),'MM/DD/RRRR')
BETWEEN TO_DATE('03/02/2008','MM/DD/RRRR')
AND TO_DATE('03/02/2008','MM/DD/RRRR')
AND UPPER(dsnh.product_class_code) <> UPPER('3P')
- You didn't post an EXPLAIN PLAN
SQL> /
PLAN_TABLE_OUTPUT
Plan hash value: 1508264907
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Inst |IN-OUT|
| 0 | SELECT STATEMENT | | 1 | 750 | 354K (1)| 01:10:54 | | |
| 1 | HASH UNIQUE | | 1 | 750 | 354K (1)| 01:10:54 | | |
|* 2 | FILTER | | | | | | | |
|* 3 | HASH JOIN | | 1 | 714 | 351K (1)| 01:10:24 | | |
| 4 | MERGE JOIN CARTESIAN | | 1 | 95 | 12 (0)| 00:00:01 | | |
| 5 | MERGE JOIN CARTESIAN | | 1 | 64 | 9 (0)| 00:00:01 | | |
PLAN_TABLE_OUTPUT
| 6 | MERGE JOIN CARTESIAN| | 1 | 60 | 6 (0)| 00:00:01 | | |
|* 7 | TABLE ACCESS FULL | OPC_REPAIR_SCENARIO_1 | 1 | 27 | 3 (0)| 00:00:01 | | |
| 8 | BUFFER SORT | | 1 | 33 | 3 (0)| 00:00:01 | | |
|* 9 | TABLE ACCESS FULL | OPC_NOTIF_TYPE_1 | 1 | 33 | 3 (0)| 00:00:01 | | |
| 10 | BUFFER SORT | | 2 | 8 | 6 (0)| 00:00:01 | | |
| 11 | TABLE ACCESS FULL | OPC_SALES_ORG_1 | 2 | 8 | 3 (0)| 00:00:01 | | |
| 12 | BUFFER SORT | | 2 | 62 | 9 (0)| 00:00:01 | | |
|* 13 | TABLE ACCESS FULL | OPC_SALES_DISTRICT_1 | 2 | 62 | 3 (0)| 00:00:01 | | |
|* 14 | FILTER | | 2273 | 1374K| 351K (1)| 01:10:24 | | |
| 15 | REMOTE | | | | | | ASRDMP | R->S |
|* 16 | TABLE ACCESS FULL | OPC_NOTIF_TYPE_1 | 1 | 39 | 3 (0)| 00:00:01 | | |
PLAN_TABLE_OUTPUT
Predicate Information (identified by operation id):
2 - filter( NOT EXISTS (SELECT /*+ */ 0 FROM "OPC_NOTIF_TYPE_1" "OPC_NOTIF_TYPE_1" WHERE
"SERVICE_DESCRIPTION"='Carry In' AND "REPORT_NAME"='NEW REPAIR VOLUME' AND LNNVL(UPPER(:B1)||' -
'||UPPER(:B2)<>UPPER("NOTIF_TYPE")||' - '||UPPER("CANCEL_FLAG_VALUE"))))
3 - access(UPPER("DSNH"."NOTIF_TYPE")=UPPER("NOTIF_TYPE") AND
"REPAIR_SCENARIO"=TO_NUMBER("DSNH"."REPAIR_SCENARIO") AND "SALES_ORG_ID"=TO_NUMBER("DSNH"."SALES_ORG_ID")
AND UPPER("SC"."SALES_DISTRICT")=UPPER("SALES_DISTRICT"))
PLAN_TABLE_OUTPUT
7 - filter("REPORT_NAME"='NEW REPAIR VOLUME' AND "SERVICE_DESCRIPTION"='Carry In')
9 - filter("SERVICE_DESCRIPTION"='Carry In' AND "REPORT_NAME"='NEW REPAIR VOLUME')
13 - filter("SERVICE_DESCRIPTION"='Carry In' AND "REPORT_NAME"='NEW REPAIR VOLUME')
14 - filter(TO_DATE(TO_CHAR(INTERNAL_FUNCTION("DSNH"."NOTIFICATION_CREATION_DT"),'MM/DD/RRRR'),'MM/DD/RRR
R')<=TO_DATE('2008-03-02 00:00:00', 'yyyy-mm-dd hh24:mi:ss') AND
TO_DATE(TO_CHAR(INTERNAL_FUNCTION("DSNH"."NOTIFICATION_CREATION_DT"),'MM/DD/RRRR'),'MM/DD/RRRR')>=TO_DATE('
2008-03-02 00:00:00', 'yyyy-mm-dd hh24:mi:ss'))
16 - filter("SERVICE_DESCRIPTION"='Carry In' AND "REPORT_NAME"='NEW REPAIR VOLUME' AND
LNNVL(UPPER(:B1)||' - '||UPPER(:B2)<>UPPER("NOTIF_TYPE")||' - '||UPPER("CANCEL_FLAG_VALUE")))
Remote SQL Information (identified by operation id):
PLAN_TABLE_OUTPUT
15 - SELECT "A1"."NOTIF_NR","A1"."SALES_ORG_ID","A1"."SALES_ORG_NAME","A1"."FISCAL_YEAR","A1"."FISCAL_PER
IOD","A1"."FISCAL_WEEK_PERIOD","A1"."NOTIF_TYPE","A1"."NOTIF_TYPE_DESC","A1"."REPAIR_SCENARIO","A1"."PRODUC
T_CLASS_CODE","A1"."SHIPTO_PARTNER_NR","A1"."SALES_CHANNEL","A1"."CHANNEL_TYPE","A1"."HEADER_WARRANTY_CODE"
,"A1"."DEPOT_PARTNER_NAME","A1"."SHIPTO_PARTNER_NAME","A1"."SHIPTO_PARTNER_NR","A1"."NOTIF_NR","A1"."NOTIF_
TYPE","A1"."NOTIF_TYPE","A1"."REPAIR_SCENARIO","A1"."SALES_ORG_ID","A1"."HEADER_WARRANTY_CODE","A1"."NOTIFI
CATION_CREATION_DT","A1"."PRODUCT_CLASS_CODE","A2"."SAP_CUST_NO","A2"."SALES_DISTRICT","A3"."DOC_NR","A3"."
SYS_STATUS","A4"."EXT_STATUS","A4"."EXT_STATUS" FROM "DN_SERVICE_NOTIFICATION_HDR" "A1","SAP_CUSTOMER"
"A2","SYS_STATUSES" "A3","EXTERNAL_INTERNAL_TBL" "A4" WHERE "A3"."SYS_STATUS"="A4"."EXT_STATUS" AND
"A1"."NOTIF_NR"="A3"."DOC_NR" AND "A1"."SHIPTO_PARTNER_NR"="A2"."SAP_CUST_NO" AND
PLAN_TABLE_OUTPUT
UPPER("A1"."PRODUCT_CLASS_CODE")<>'3P' AND "A1"."HEADER_WARRANTY_CODE"<>'OO' (accessing 'ASRDMP' )
- you did post only a very small section of the wait analysis. -
Performance issue after 10G upgrade.
All,
We recently upgraded to 10G (Version:10.2.0.3.0) after which the below query causing the problem. This query is written in a pl/sql package called by a Perl program. The Perl program is running forever without completion during some attempts and sometimes it is completing very fast. We did some kind of debugging and found that everytime the program is getting stucked up at this below given query and not at all proceeding from here even if we leave it for 2 - 3 days. During a successful attempt it completes in 3 - 4 hrs. This query is taking 2 explain plan as given below and it seems one of them is best and the other one is worst. Plan 2 is best and plan 1 is worst.
Is there any suggestion in fixing this and the reason why two explain plans are picking up?....Num of records on the tables is as given below...
Can you please provide me some detailed information as i'm a beginner in these performance tuning concepts?
Your help will be much appreciated..
Tables No. of records
ult_cust_master 551925
us_state_county 3223
customer 1559
turfbuilder_group2_empcnt_tmp 44K
ult_cust_sale 2430143
ucsi_item 9714371
SELECT cust.cust_num, cust.cust_name, cust.emp_count, cust.sic1,
cust.s1_description, NVL (cust_sale.qty, 0) qty,
NVL (cust_sale.mot_amt, 0) mot_amt,
NVL (cust_sale.cust_amt, 0) cust_amt, cust.min_sale_dt,
cust.max_sale_dt, cust.cust_status
FROM (SELECT DISTINCT ucm.cust_num, f.cust_name cust_name,
NVL (te.tet_emp_count, 0) emp_count, b.min_sale_dt,
b.max_sale_dt, f.cust_status, sc1.sic1,
sc1.s1_description
FROM ult_cust_master ucm,
us_state_county u,
customer f,
(SELECT div_cd, ctry_cd, cust_num,
MIN (ucs_dt) min_sale_dt,
MAX (ucs_dt) max_sale_dt
FROM ult_cust_sale
WHERE div_cd = :b4
AND ctry_cd = :b3
AND rec_status = 'A'
GROUP BY div_cd, ctry_cd, cust_num) b,
sic1 sc1,
(SELECT tet_code, tet_vm_code, tet_type,
tet_emp_count
FROM turfbuilder_group2_empcnt_tmp
WHERE tet_type = 'D') te
WHERE f.div_cd = ucm.div_cd
AND f.ctry_cd = ucm.ctry_cd
AND f.cust_num = ucm.cust_num
AND b.div_cd = ucm.div_cd
AND b.ctry_cd = ucm.ctry_cd
AND b.cust_num = ucm.cust_num
AND te.tet_code(+) = ucm.cust_num
AND te.tet_vm_code = sc1.sic1
AND f.div_cd = :b4
AND f.ctry_cd = :b3
AND ucm.ucm_stcnty_fips_cd = u.usc_st_cnty_cd
AND UPPER (u.usc_state_abbrev) NOT IN ('PR', 'VI')
AND ucm.rec_status = 'A'
AND u.rec_status = 'A'
AND sc1.rec_status = 'A'
AND f.cust_imp21_dealer_fg = 'Y'
AND NVL (f.cust_test_dealer_fg, 'N') <> 'Y') cust,
(SELECT c.cust_num cust_num, sc2.sic1,
SUM (DECODE (a.ucsii_unit_fg,
'Y', a.ucsii_qty * 1,
a.ucsii_qty * 0
) qty,
SUM (a.ucsii_qty * a.ucsii_mot_unit_pr) mot_amt,
SUM (a.ucsii_qty * a.ucsii_ult_unit_pr) cust_amt
FROM ucsi_item a,
ult_cust_sale b,
ult_cust_master c,
sic2 sc2,
us_state_county u
WHERE a.div_cd = b.div_cd
AND a.ctry_cd = b.ctry_cd
AND a.cust_num = b.cust_num
AND a.ucm_mailbox_num = b.ucm_mailbox_num
AND a.ucm_seq = b.ucm_seq
AND a.ucs_seq = b.ucs_seq
AND c.div_cd = b.div_cd
AND c.ctry_cd = b.ctry_cd
AND c.cust_num = b.cust_num
AND c.ucm_mailbox_num = b.ucm_mailbox_num
AND c.ucm_seq = b.ucm_seq
AND SUBSTR (c.ucm_sic_cd, 1, 2) = sc2.sic2
AND c.ucm_stcnty_fips_cd = u.usc_st_cnty_cd
AND a.ucsii_in_apmr_fg = 'Y'
AND a.ucsii_audit_data_cd = 'G'
AND a.ucsii_contract_id IN
('BRANDED',
'CTR',
'WARIS',
'RADIUS',
'BRNDCONV',
'BRNDTRNK'
AND ( (a.ucsii_unit_fg = 'Y')
OR (a.ucsii_unit_fg = 'N' AND a.ucsii_item_num LIKE '%.%')
AND c.div_cd = :b4
AND c.ctry_cd = :b3
AND UPPER (u.usc_state_abbrev) NOT IN ('PR', 'VI')
AND u.rec_status = 'A'
AND c.rec_status = 'A'
AND a.rec_status = 'A'
AND sc2.rec_status = 'A'
AND b.ua_cd = 'ENDCUST'
AND b.rec_status = 'A'
AND b.ucs_dt BETWEEN TO_DATE (:b2, 'dd mon yyyy')
AND TO_DATE (:b1, 'dd mon yyyy')
GROUP BY c.cust_num, sc2.sic1) cust_sale
WHERE cust.cust_num = cust_sale.cust_num(+) AND cust.sic1 = cust_sale.sic1(+)------------------------------------------------------------------------------------------------------------------------
{color:blue}
Execution Plan – 1:
Plan hash value: 2237978112
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | | | 643 (100)| |
|* 1 | HASH JOIN OUTER | | 1 | 175 | 643 (2)| 00:00:08 |
| 2 | VIEW | | 1 | 118 | 74 (5)| 00:00:01 |
| 3 | HASH UNIQUE | | 1 | 310 | 74 (5)| 00:00:01 |
| 4 | HASH GROUP BY | | 1 | 310 | 74 (5)| 00:00:01 |
|* 5 | FILTER | | | | | |
| 6 | NESTED LOOPS | | 1 | 310 | 73 (3)| 00:00:01 |
| 7 | NESTED LOOPS | | 1 | 278 | 70 (2)| 00:00:01 |
| 8 | NESTED LOOPS | | 1 | 187 | 69 (2)| 00:00:01 |
| 9 | NESTED LOOPS | | 1 | 148 | 68 (2)| 00:00:01 |
| 10 | NESTED LOOPS | | 1 | 100 | 52 (2)| 00:00:01 |
|* 11 | TABLE ACCESS FULL | TURFBUILDER_GROUP2_EMPCNT_TMP | 1 | 52 | 51 (2)| 00:00:01 |
|* 12 | TABLE ACCESS BY INDEX ROWID| SIC1 | 1 | 48 | 1 (0)| 00:00:01 |
|* 13 | INDEX UNIQUE SCAN | SYS_C001278 | 1 | | 1 (0)| 00:00:01 |
|* 14 | TABLE ACCESS BY INDEX ROWID | ULT_CUST_MASTER | 517 | 24816 | 16 (0)| 00:00:01 |
|* 15 | INDEX RANGE SCAN | XIF9ULT_CUST_MASTER | 505 | | 1 (0)| 00:00:01 |
|* 16 | TABLE ACCESS BY INDEX ROWID | US_STATE_COUNTY | 1 | 39 | 1 (0)| 00:00:01 |
|* 17 | INDEX UNIQUE SCAN | XPKSTATE_COUNTY | 1 | | 1 (0)| 00:00:01 |
|* 18 | TABLE ACCESS BY INDEX ROWID | CUSTOMER | 1 | 91 | 1 (0)| 00:00:01 |
|* 19 | INDEX UNIQUE SCAN | XPKCUSTOMER | 1 | | 1 (0)| 00:00:01 |
|* 20 | INDEX RANGE SCAN | XIE1ULT_CUST_SALE | 13514 | 422K| 2 (0)| 00:00:01 |
| 21 | VIEW | | 1 | 57 | 569 (2)| 00:00:07 |
| 22 | HASH GROUP BY | | 1 | 209 | 569 (2)| 00:00:07 |
|* 23 | FILTER | | | | | |
|* 24 | TABLE ACCESS BY INDEX ROWID | UCSI_ITEM | 1 | 74 | 1 (0)| 00:00:01 |
| 25 | NESTED LOOPS | | 1 | 209 | 568 (1)| 00:00:07 |
| 26 | NESTED LOOPS | | 1 | 135 | 567 (1)| 00:00:07 |
|* 27 | HASH JOIN | | 1491 | 110K| 118 (3)| 00:00:02 |
|* 28 | TABLE ACCESS FULL | SIC2 | 83 | 996 | 2 (0)| 00:00:01 |
| 29 | TABLE ACCESS BY INDEX ROWID | ULT_CUST_MASTER | 186 | 9858 | 13 (0)| 00:00:01 |
| 30 | NESTED LOOPS | | 1500 | 96000 | 115 (2)| 00:00:02 |
|* 31 | TABLE ACCESS FULL | US_STATE_COUNTY | 8 | 88 | 9 (12)| 00:00:01 |
|* 32 | INDEX RANGE SCAN | TEST | 186 | | 1 (0)| 00:00:01 |
|* 33 | TABLE ACCESS BY INDEX ROWID | ULT_CUST_SALE | 1 | 59 | 1 (0)| 00:00:01 |
|* 34 | INDEX RANGE SCAN | XIE1ULT_CUST_SALE | 1 | | 1 (0)| 00:00:01 |
|* 35 | INDEX RANGE SCAN | XPKUCSI_ITEM | 1 | | 1 (0)| 00:00:01 |
Predicate Information (identified by operation id):
1 - access("CUST"."CUST_NUM"="CUST_SALE"."CUST_NUM" AND "CUST"."SIC1"="CUST_SALE"."SIC1")
5 - filter((:B3=:B3 AND :B4=:B4))
11 - filter("TET_TYPE"='D')
12 - filter("SC1"."REC_STATUS"='A')
13 - access("TET_VM_CODE"="SC1"."SIC1")
14 - filter("UCM"."REC_STATUS"='A')
15 - access("UCM"."DIV_CD"=:B4 AND "UCM"."CTRY_CD"=:B3 AND "TET_CODE"="UCM"."CUST_NUM")
filter(("UCM"."DIV_CD"=:B4 AND "UCM"."CTRY_CD"=:B3))
16 - filter((UPPER("U"."USC_STATE_ABBREV")<>'PR' AND UPPER("U"."USC_STATE_ABBREV")<>'VI' AND
"U"."REC_STATUS"='A'))
17 - access("UCM"."UCM_STCNTY_FIPS_CD"="U"."USC_ST_CNTY_CD")
18 - filter(("F"."CUST_IMP21_DEALER_FG"='Y' AND NVL("F"."CUST_TEST_DEALER_FG",'N')<>'Y'))
19 - access("F"."DIV_CD"=:B4 AND "F"."CTRY_CD"=:B3 AND "F"."CUST_NUM"="UCM"."CUST_NUM")
filter(("F"."DIV_CD"=:B4 AND "F"."CTRY_CD"=:B3))
20 - access("DIV_CD"=:B4 AND "CTRY_CD"=:B3 AND "CUST_NUM"="UCM"."CUST_NUM" AND "REC_STATUS"='A')
filter(("DIV_CD"=:B4 AND "CTRY_CD"=:B3 AND "REC_STATUS"='A'))
23 - filter(TO_DATE(:B2,'dd mon yyyy')<=TO_DATE(:B1,'dd mon yyyy'))
24 - filter((("A"."UCSII_UNIT_FG"='Y' OR ("A"."UCSII_ITEM_NUM" LIKE '%.%' AND "A"."UCSII_UNIT_FG"='N')) AND
"A"."UCSII_IN_APMR_FG"='Y' AND INTERNAL_FUNCTION("A"."UCSII_CONTRACT_ID") AND "A"."UCSII_AUDIT_DATA_CD"='G'
AND "A"."REC_STATUS"='A'))
27 - access("SC2"."SIC2"=SUBSTR("C"."UCM_SIC_CD",1,2))
28 - filter("SC2"."REC_STATUS"='A')
31 - filter((UPPER("U"."USC_STATE_ABBREV")<>'PR' AND UPPER("U"."USC_STATE_ABBREV")<>'VI' AND
"U"."REC_STATUS"='A'))
32 - access("C"."UCM_STCNTY_FIPS_CD"="U"."USC_ST_CNTY_CD" AND "C"."DIV_CD"=:B4 AND "C"."CTRY_CD"=:B3 AND
"C"."REC_STATUS"='A')
33 - filter(("B"."UA_CD"='ENDCUST' AND "C"."UCM_MAILBOX_NUM"="B"."UCM_MAILBOX_NUM"))
34 - access("B"."DIV_CD"=:B4 AND "B"."CTRY_CD"=:B3 AND "C"."CUST_NUM"="B"."CUST_NUM" AND
"C"."UCM_SEQ"="B"."UCM_SEQ" AND "B"."UCS_DT">=TO_DATE(:B2,'dd mon yyyy') AND "B"."REC_STATUS"='A' AND
"B"."UCS_DT"<=TO_DATE(:B1,'dd mon yyyy'))
filter("B"."REC_STATUS"='A')
35 - access("A"."DIV_CD"=:B4 AND "A"."CTRY_CD"=:B3 AND "A"."CUST_NUM"="B"."CUST_NUM" AND
"A"."UCM_MAILBOX_NUM"="B"."UCM_MAILBOX_NUM" AND "A"."UCM_SEQ"="B"."UCM_SEQ" AND "A"."UCS_SEQ"="B"."UCS_SEQ")
{color}
{color:green}
Execution Plan – 2:
Plan hash value: 2023039777
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | | | | 3341 (100)| |
|* 1 | HASH JOIN RIGHT OUTER | | 12967 | 2216K| | 3341 (5)| 00:00:41 |
| 2 | VIEW | | 1 | 57 | | 607 (6)| 00:00:08 |
| 3 | HASH GROUP BY | | 1 | 209 | | 607 (6)| 00:00:08 |
|* 4 | FILTER | | | | | | |
|* 5 | TABLE ACCESS BY INDEX ROWID | UCSI_ITEM | 1 | 74 | | 1 (0)| 00:00:01 |
| 6 | NESTED LOOPS | | 1 | 209 | | 606 (6)| 00:00:08 |
| 7 | NESTED LOOPS | | 1 | 135 | | 605 (6)| 00:00:08 |
|* 8 | HASH JOIN | | 1 | 123 | | 604 (6)| 00:00:08 |
|* 9 | TABLE ACCESS BY INDEX ROWID| ULT_CUST_SALE | 1214 | 71626 | | 455 (7)| 00:00:06 |
|* 10 | INDEX SKIP SCAN | XIE1ULT_CUST_SALE | 1 | | | 455 (7)| 00:00:06 |
| 11 | TABLE ACCESS BY INDEX ROWID| ULT_CUST_MASTER | 245 | 12985 | | 17 (0)| 00:00:01 |
| 12 | NESTED LOOPS | | 1971 | 123K| | 148 (2)| 00:00:02 |
|* 13 | TABLE ACCESS FULL | US_STATE_COUNTY | 8 | 88 | | 9 (12)| 00:00:01 |
|* 14 | INDEX RANGE SCAN | TEST | 245 | | | 1 (0)| 00:00:01 |
|* 15 | TABLE ACCESS BY INDEX ROWID | SIC2 | 1 | 12 | | 1 (0)| 00:00:01 |
|* 16 | INDEX UNIQUE SCAN | XPKSIC2 | 1 | | | 1 (0)| 00:00:01 |
|* 17 | INDEX RANGE SCAN | XPKUCSI_ITEM | 1 | | | 1 (0)| 00:00:01 |
| 18 | VIEW | | 12967 | 1494K| | 2732 (5)| 00:00:33 |
| 19 | HASH UNIQUE | | 12967 | 3254K| 6936K| 2732 (5)| 00:00:33 |
|* 20 | HASH JOIN | | 12967 | 3254K| | 1998 (6)| 00:00:24 |
| 21 | VIEW | | 410 | 16400 | | 1781 (5)| 00:00:22 |
| 22 | HASH GROUP BY | | 410 | 13120 | | 1781 (5)| 00:00:22 |
|* 23 | FILTER | | | | | | |
|* 24 | INDEX RANGE SCAN | XIE1ULT_CUST_SALE | 1963K| 59M| | 1781 (5)| 00:00:22 |
|* 25 | HASH JOIN | | 4792 | 1015K| | 215 (7)| 00:00:03 |
|* 26 | TABLE ACCESS FULL | SIC1 | 11 | 528 | | 2 (0)| 00:00:01 |
|* 27 | HASH JOIN | | 4792 | 790K| | 212 (6)| 00:00:03 |
|* 28 | TABLE ACCESS BY INDEX ROWID | CUSTOMER | 1003 | 79237 | | 4 (0)| 00:00:01 |
|* 29 | INDEX RANGE SCAN | XIF317CUSTOMER | 1371 | | | 1 (0)| 00:00:01 |
|* 30 | HASH JOIN | | 4794 | 421K| | 207 (6)| 00:00:03 |
| 31 | TABLE ACCESS BY INDEX ROWID | ULT_CUST_MASTER | 245 | 8820 | | 17 (0)| 00:00:01 |
| 32 | NESTED LOOPS | | 1971 | 136K| | 148 (2)| 00:00:02 |
|* 33 | TABLE ACCESS FULL | US_STATE_COUNTY | 8 | 280 | | 9 (12)| 00:00:01 |
|* 34 | INDEX RANGE SCAN | TEST | 245 | | | 1 (0)| 00:00:01 |
|* 35 | TABLE ACCESS FULL | TURFBUILDER_GROUP2_EMPCNT_TMP | 8914 | 165K| | 58 (14)| 00:00:01 |
Predicate Information (identified by operation id):
1 - access("CUST"."CUST_NUM"="CUST_SALE"."CUST_NUM" AND "CUST"."SIC1"="CUST_SALE"."SIC1")
4 - filter(TO_DATE(:B2,'dd mon yyyy')<=TO_DATE(:B1,'dd mon yyyy'))
5 - filter((("A"."UCSII_UNIT_FG"='Y' OR ("A"."UCSII_ITEM_NUM" LIKE '%.%' AND "A"."UCSII_UNIT_FG"='N')) AND
"A"."UCSII_IN_APMR_FG"='Y' AND INTERNAL_FUNCTION("A"."UCSII_CONTRACT_ID") AND "A"."UCSII_AUDIT_DATA_CD"='G' AND
"A"."REC_STATUS"='A'))
8 - access("C"."DIV_CD"="B"."DIV_CD" AND "C"."CTRY_CD"="B"."CTRY_CD" AND "C"."CUST_NUM"="B"."CUST_NUM" AND
"C"."UCM_MAILBOX_NUM"="B"."UCM_MAILBOX_NUM" AND "C"."UCM_SEQ"="B"."UCM_SEQ")
9 - filter("B"."UA_CD"='ENDCUST')
10 - access("B"."DIV_CD"=:B4 AND "B"."CTRY_CD"=:B3 AND "B"."UCS_DT">=TO_DATE(:B2,'dd mon yyyy') AND
"B"."REC_STATUS"='A' AND "B"."UCS_DT"<=TO_DATE(:B1,'dd mon yyyy'))
filter(("B"."UCS_DT">=TO_DATE(:B2,'dd mon yyyy') AND "B"."REC_STATUS"='A' AND "B"."UCS_DT"<=TO_DATE(:B1,'dd
mon yyyy')))
13 - filter((UPPER("U"."USC_STATE_ABBREV")<>'PR' AND UPPER("U"."USC_STATE_ABBREV")<>'VI' AND "U"."REC_STATUS"='A'))
14 - access("C"."UCM_STCNTY_FIPS_CD"="U"."USC_ST_CNTY_CD" AND "C"."DIV_CD"=:B4 AND "C"."CTRY_CD"=:B3 AND
"C"."REC_STATUS"='A')
15 - filter("SC2"."REC_STATUS"='A')
16 - access("SC2"."SIC2"=SUBSTR("C"."UCM_SIC_CD",1,2))
17 - access("A"."DIV_CD"=:B4 AND "A"."CTRY_CD"=:B3 AND "A"."CUST_NUM"="B"."CUST_NUM" AND
"A"."UCM_MAILBOX_NUM"="B"."UCM_MAILBOX_NUM" AND "A"."UCM_SEQ"="B"."UCM_SEQ" AND "A"."UCS_SEQ"="B"."UCS_SEQ")
20 - access("B"."DIV_CD"="UCM"."DIV_CD" AND "B"."CTRY_CD"="UCM"."CTRY_CD" AND "B"."CUST_NUM"="UCM"."CUST_NUM")
23 - filter((:B3=:B3 AND :B4=:B4))
24 - access("DIV_CD"=:B4 AND "CTRY_CD"=:B3 AND "REC_STATUS"='A')
filter(("DIV_CD"=:B4 AND "CTRY_CD"=:B3 AND "DIV_CD"=:B4 AND "CTRY_CD"=:B3 AND "REC_STATUS"='A'))
25 - access("TET_VM_CODE"="SC1"."SIC1")
26 - filter("SC1"."REC_STATUS"='A')
27 - access("F"."DIV_CD"="UCM"."DIV_CD" AND "F"."CTRY_CD"="UCM"."CTRY_CD" AND "F"."CUST_NUM"="UCM"."CUST_NUM")
28 - filter(("F"."DIV_CD"=:B4 AND "F"."CUST_IMP21_DEALER_FG"='Y' AND NVL("F"."CUST_TEST_DEALER_FG",'N')<>'Y'))
29 - access("F"."CTRY_CD"=:B3)
30 - access("TET_CODE"="UCM"."CUST_NUM")
33 - filter((UPPER("U"."USC_STATE_ABBREV")<>'PR' AND UPPER("U"."USC_STATE_ABBREV")<>'VI' AND "U"."REC_STATUS"='A'))
34 - access("UCM"."UCM_STCNTY_FIPS_CD"="U"."USC_ST_CNTY_CD" AND "UCM"."DIV_CD"=:B4 AND "UCM"."CTRY_CD"=:B3 AND
"UCM"."REC_STATUS"='A')
35 - filter("TET_TYPE"='D')
{color}
Edited by: user3030284 on Oct 28, 2008 9:42 PM<p>
{size:12}
All,
</p>
<p>
We recently upgraded to 10G (Version:10.2.0.3.0) after which the below query causing the problem. This query is written in a pl/sql package called by a Perl program. The Perl program is running forever without completion during some attempts and sometimes it is completing very fast. We did some kind of debugging and found that everytime the program is getting stucked up at this below given query and not at all proceeding from here even if we leave it for 2 - 3 days. During a successful attempt it completes in 3 - 4 hrs. This query is taking 2 explain plan as given below and it seems one of them is best and the other one is worst. Plan 2 is best and plan 1 is worst.
Is there any suggestion in fixing this and the reason why two explain plans are picking up?....Num of records on the tables is as given below...
Can you please provide me some detailed information as i'm a beginner in these performance tuning concepts?
Your help will be much appreciated..
</p>
<p>
Tables No. of records
ult_cust_master 551925
us_state_county 3223
customer 1559
turfbuilder_group2_empcnt_tmp 44K
ult_cust_sale 2430143
ucsi_item 9714371
{size}
</p>
<p>
<br /></p><br /><p><br />/* Formatted on 2007/09/30 20:37 (Formatter Plus v4.8.5) */ <br /></p><br /><p><br />SELECT cust.cust_num, cust.cust_name, cust.emp_count, cust.sic1, <br /></p><br /><p><br />cust.s1_description, NVL (cust_sale.qty, 0) qty, <br /></p><br /><p><br />NVL (cust_sale.mot_amt, 0) mot_amt, <br /></p><br /><p><br />NVL (cust_sale.cust_amt, 0) cust_amt, cust.min_sale_dt, <br /></p><br /><p><br />cust.max_sale_dt, cust.cust_status <br /></p><br /><p><br />FROM (SELECT DISTINCT ucm.cust_num, f.cust_name cust_name, <br /></p><br /><p><br />NVL (te.tet_emp_count, 0) emp_count, b.min_sale_dt, <br /></p><br /><p><br />b.max_sale_dt, f.cust_status, sc1.sic1, <br /></p><br /><p><br />sc1.s1_description <br /></p><br /><p><br />FROM ult_cust_master ucm, <br /></p><br /><p><br />us_state_county u, <br /></p><br /><p><br />customer f, <br /></p><br /><p><br />(SELECT div_cd, ctry_cd, cust_num, <br /></p><br /><p><br />MIN (ucs_dt) min_sale_dt, <br /></p><br /><p><br />MAX (ucs_dt) max_sale_dt <br /></p><br /><p><br />FROM ult_cust_sale <br /></p><br /><p><br />WHERE div_cd = :b4 <br /></p><br /><p><br />AND ctry_cd = :b3 <br /></p><br /><p><br />AND rec_status = 'A' <br /></p><br /><p><br />GROUP BY div_cd, ctry_cd, cust_num) b, <br /></p><br /><p><br />sic1 sc1, <br /></p><br /><p><br />(SELECT tet_code, tet_vm_code, tet_type, <br /></p><br /><p><br />tet_emp_count <br /></p><br /><p><br />FROM turfbuilder_group2_empcnt_tmp <br /></p><br /><p><br />WHERE tet_type = 'D') te <br /></p><br /><p><br />WHERE f.div_cd = ucm.div_cd <br /></p><br /><p><br />AND f.ctry_cd = ucm.ctry_cd <br /></p><br /><p><br />AND f.cust_num = ucm.cust_num <br /></p><br /><p><br />AND b.div_cd = ucm.div_cd <br /></p><br /><p><br />AND b.ctry_cd = ucm.ctry_cd <br /></p><br /><p><br />AND b.cust_num = ucm.cust_num <br /></p><br /><p><br />AND te.tet_code(+) = ucm.cust_num <br /></p><br /><p><br />AND te.tet_vm_code = sc1.sic1 <br /></p><br /><p><br />AND f.div_cd = :b4 <br /></p><br /><p><br />AND f.ctry_cd = :b3 <br /></p><br /><p><br />AND ucm.ucm_stcnty_fips_cd = u.usc_st_cnty_cd <br /></p><br /><p><br />AND UPPER (u.usc_state_abbrev) NOT IN ('PR', 'VI') <br /></p><br /><p><br />AND ucm.rec_status = 'A' <br /></p><br /><p><br />AND u.rec_status = 'A' <br /></p><br /><p><br />AND sc1.rec_status = 'A' <br /></p><br /><p><br />AND f.cust_imp21_dealer_fg = 'Y' <br /></p><br /><p><br />AND NVL (f.cust_test_dealer_fg, 'N') <> 'Y') cust, <br /></p><br /><p><br />(SELECT c.cust_num cust_num, sc2.sic1, <br /></p><br /><p><br />SUM (DECODE (a.ucsii_unit_fg, <br /></p><br /><p><br />'Y', a.ucsii_qty * 1, <br /></p><br /><p><br />a.ucsii_qty * 0 <br /></p><br /><p><br />) <br /></p><br /><p><br />) qty, <br /></p><br /><p><br />SUM (a.ucsii_qty * a.ucsii_mot_unit_pr) mot_amt, <br /></p><br /><p><br />SUM (a.ucsii_qty * a.ucsii_ult_unit_pr) cust_amt <br /></p><br /><p><br />FROM ucsi_item a, <br /></p><br /><p><br />ult_cust_sale b, <br /></p><br /><p><br />ult_cust_master c, <br /></p><br /><p><br />sic2 sc2, <br /></p><br /><p><br />us_state_county u <br /></p><br /><p><br />WHERE a.div_cd = b.div_cd <br /></p><br /><p><br />AND a.ctry_cd = b.ctry_cd <br /></p><br /><p><br />AND a.cust_num = b.cust_num <br /></p><br /><p><br />AND a.ucm_mailbox_num = b.ucm_mailbox_num <br /></p><br /><p><br />AND a.ucm_seq = b.ucm_seq <br /></p><br /><p><br />AND a.ucs_seq = b.ucs_seq <br /></p><br /><p><br />AND c.div_cd = b.div_cd <br /></p><br /><p><br />AND c.ctry_cd = b.ctry_cd <br /></p><br /><p><br />AND c.cust_num = b.cust_num <br /></p><br /><p><br />AND c.ucm_mailbox_num = b.ucm_mailbox_num <br /></p><br /><p><br />AND c.ucm_seq = b.ucm_seq <br /></p><br /><p><br />AND SUBSTR (c.ucm_sic_cd, 1, 2) = sc2.sic2 <br /></p><br /><p><br />AND c.ucm_stcnty_fips_cd = u.usc_st_cnty_cd <br /></p><br /><p><br />AND a.ucsii_in_apmr_fg = 'Y' <br /></p><br /><p><br />AND a.ucsii_audit_data_cd = 'G' <br /></p><br /><p><br />AND a.ucsii_contract_id IN <br /></p><br /><p><br />('BRANDED', <br /></p><br /><p><br />'CTR', <br /></p><br /><p><br />'WARIS', <br /></p><br /><p><br />'RADIUS', <br /></p><br /><p><br />'BRNDCONV', <br /></p><br /><p><br />'BRNDTRNK' <br /></p><br /><p><br />) <br /></p><br /><p><br />AND ( (a.ucsii_unit_fg = 'Y') <br /></p><br /><p><br />OR (a.ucsii_unit_fg = 'N' AND a.ucsii_item_num LIKE '%.%') <br /></p><br /><p><br />) <br /></p><br /><p><br />AND c.div_cd = :b4 <br /></p><br /><p><br />AND c.ctry_cd = :b3 <br /></p><br /><p><br />AND UPPER (u.usc_state_abbrev) NOT IN ('PR', 'VI') <br /></p><br /><p><br />AND u.rec_status = 'A' <br /></p><br /><p><br />AND c.rec_status = 'A' <br /></p><br /><p><br />AND a.rec_status = 'A' <br /></p><br /><p><br />AND sc2.rec_status = 'A' <br /></p><br /><p><br />AND b.ua_cd = 'ENDCUST' <br /></p><br /><p><br />AND b.rec_status = 'A' <br /></p><br /><p><br />AND b.ucs_dt BETWEEN TO_DATE (:b2, 'dd mon yyyy') <br /></p><br /><p><br />AND TO_DATE (:b1, 'dd mon yyyy') <br /></p><br /><p><br />GROUP BY c.cust_num, sc2.sic1) cust_sale <br /></p><br /><p><br />WHERE cust.cust_num = cust_sale.cust_num(+) AND cust.sic1 = cust_sale.sic1(+) <br /></p><br /><p><br /><strong></strong>
</p>
<p>
{color:green}
</p>
<p>
Explain Plan -- 1:
</p>
<p>
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | | | 643 (100)| |
|* 1 | HASH JOIN OUTER | | 1 | 175 | 643 (2)| 00:00:08 |
| 2 | VIEW | | 1 | 118 | 74 (5)| 00:00:01 |
| 3 | HASH UNIQUE | | 1 | 310 | 74 (5)| 00:00:01 |
| 4 | HASH GROUP BY | | 1 | 310 | 74 (5)| 00:00:01 |
|* 5 | FILTER | | | | | |
| 6 | NESTED LOOPS | | 1 | 310 | 73 (3)| 00:00:01 |
| 7 | NESTED LOOPS | | 1 | 278 | 70 (2)| 00:00:01 |
| 8 | NESTED LOOPS | | 1 | 187 | 69 (2)| 00:00:01 |
| 9 | NESTED LOOPS | | 1 | 148 | 68 (2)| 00:00:01 |
| 10 | NESTED LOOPS | | 1 | 100 | 52 (2)| 00:00:01 |
|* 11 | TABLE ACCESS FULL | TURFBUILDER_GROUP2_EMPCNT_TMP | 1 | 52 | 51 (2)| 00:00:01 |
|* 12 | TABLE ACCESS BY INDEX ROWID| SIC1 | 1 | 48 | 1 (0)| 00:00:01 |
|* 13 | INDEX UNIQUE SCAN | SYS_C001278 | 1 | | 1 (0)| 00:00:01 |
|* 14 | TABLE ACCESS BY INDEX ROWID | ULT_CUST_MASTER | 517 | 24816 | 16 (0)| 00:00:01 |
|* 15 | INDEX RANGE SCAN | XIF9ULT_CUST_MASTER | 505 | | 1 (0)| 00:00:01 |
|* 16 | TABLE ACCESS BY INDEX ROWID | US_STATE_COUNTY | 1 | 39 | 1 (0)| 00:00:01 |
|* 17 | INDEX UNIQUE SCAN | XPKSTATE_COUNTY | 1 | | 1 (0)| 00:00:01 |
|* 18 | TABLE ACCESS BY INDEX ROWID | CUSTOMER | 1 | 91 | 1 (0)| 00:00:01 |
|* 19 | INDEX UNIQUE SCAN | XPKCUSTOMER | 1 | | 1 (0)| 00:00:01 |
|* 20 | INDEX RANGE SCAN | XIE1ULT_CUST_SALE | 13514 | 422K| 2 (0)| 00:00:01 |
| 21 | VIEW | | 1 | 57 | 569 (2)| 00:00:07 |
| 22 | HASH GROUP BY | | 1 | 209 | 569 (2)| 00:00:07 |
|* 23 | FILTER | | | | | |
|* 24 | TABLE ACCESS BY INDEX ROWID | UCSI_ITEM | 1 | 74 | 1 (0)| 00:00:01 |
| 25 | NESTED LOOPS | | 1 | 209 | 568 (1)| 00:00:07 |
| 26 | NESTED LOOPS | | 1 | 135 | 567 (1)| 00:00:07 |
|* 27 | HASH JOIN | | 1491 | 110K| 118 (3)| 00:00:02 |
|* 28 | TABLE ACCESS FULL | SIC2 | 83 | 996 | 2 (0)| 00:00:01 |
| 29 | TABLE ACCESS BY INDEX ROWID | ULT_CUST_MASTER | 186 | 9858 | 13 (0)| 00:00:01 |
| 30 | NESTED LOOPS | | 1500 | 96000 | 115 (2)| 00:00:02 |
|* 31 | TABLE ACCESS FULL | US_STATE_COUNTY | 8 | 88 | 9 (12)| 00:00:01 |
|* 32 | INDEX RANGE SCAN | TEST | 186 | | 1 (0)| 00:00:01 |
|* 33 | TABLE ACCESS BY INDEX ROWID | ULT_CUST_SALE | 1 | 59 | 1 (0)| 00:00:01 |
|* 34 | INDEX RANGE SCAN | XIE1ULT_CUST_SALE | 1 | | 1 (0)| 00:00:01 |
|* 35 | INDEX RANGE SCAN | XPKUCSI_ITEM | 1 | | 1 (0)| 00:00:01 |
Predicate Information (identified by operation id):
1 - access("CUST"."CUST_NUM"="CUST_SALE"."CUST_NUM" AND "CUST"."SIC1"="CUST_SALE"."SIC1")
5 - filter((:B3=:B3 AND :B4=:B4))
11 - filter("TET_TYPE"='D')
12 - filter("SC1"."REC_STATUS"='A')
13 - access("TET_VM_CODE"="SC1"."SIC1")
14 - filter("UCM"."REC_STATUS"='A')
15 - access("UCM"."DIV_CD"=:B4 AND "UCM"."CTRY_CD"=:B3 AND "TET_CODE"="UCM"."CUST_NUM")
filter(("UCM"."DIV_CD"=:B4 AND "UCM"."CTRY_CD"=:B3))
16 - filter((UPPER("U"."USC_STATE_ABBREV")<>'PR' AND UPPER("U"."USC_STATE_ABBREV")<>'VI' AND
"U"."REC_STATUS"='A'))
17 - access("UCM"."UCM_STCNTY_FIPS_CD"="U"."USC_ST_CNTY_CD")
18 - filter(("F"."CUST_IMP21_DEALER_FG"='Y' AND NVL("F"."CUST_TEST_DEALER_FG",'N')<>'Y'))
19 - access("F"."DIV_CD"=:B4 AND "F"."CTRY_CD"=:B3 AND "F"."CUST_NUM"="UCM"."CUST_NUM")
filter(("F"."DIV_CD"=:B4 AND "F"."CTRY_CD"=:B3))
20 - access("DIV_CD"=:B4 AND "CTRY_CD"=:B3 AND "CUST_NUM"="UCM"."CUST_NUM" AND "REC_STATUS"='A')
filter(("DIV_CD"=:B4 AND "CTRY_CD"=:B3 AND "REC_STATUS"='A'))
23 - filter(TO_DATE(:B2,'dd mon yyyy')<=TO_DATE(:B1,'dd mon yyyy'))
24 - filter((("A"."UCSII_UNIT_FG"='Y' OR ("A"."UCSII_ITEM_NUM" LIKE '%.%' AND "A"."UCSII_UNIT_FG"='N')) AND
"A"."UCSII_IN_APMR_FG"='Y' AND INTERNAL_FUNCTION("A"."UCSII_CONTRACT_ID") AND "A"."UCSII_AUDIT_DATA_CD"='G'
AND "A"."REC_STATUS"='A'))
27 - access("SC2"."SIC2"=SUBSTR("C"."UCM_SIC_CD",1,2))
28 - filter("SC2"."REC_STATUS"='A')
31 - filter((UPPER("U"."USC_STATE_ABBREV")<>'PR' AND UPPER("U"."USC_STATE_ABBREV")<>'VI' AND
"U"."REC_STATUS"='A'))
32 - access("C"."UCM_STCNTY_FIPS_CD"="U"."USC_ST_CNTY_CD" AND "C"."DIV_CD"=:B4 AND "C"."CTRY_CD"=:B3 AND
"C"."REC_STATUS"='A')
33 - filter(("B"."UA_CD"='ENDCUST' AND "C"."UCM_MAILBOX_NUM"="B"."UCM_MAILBOX_NUM"))
34 - access("B"."DIV_CD"=:B4 AND "B"."CTRY_CD"=:B3 AND "C"."CUST_NUM"="B"."CUST_NUM" AND
"C"."UCM_SEQ"="B"."UCM_SEQ" AND "B"."UCS_DT">=TO_DATE(:B2,'dd mon yyyy') AND "B"."REC_STATUS"='A' AND
"B"."UCS_DT"<=TO_DATE(:B1,'dd mon yyyy'))
filter("B"."REC_STATUS"='A')
35 - access("A"."DIV_CD"=:B4 AND "A"."CTRY_CD"=:B3 AND "A"."CUST_NUM"="B"."CUST_NUM" AND
"A"."UCM_MAILBOX_NUM"="B"."UCM_MAILBOX_NUM" AND "A"."UCM_SEQ"="B"."UCM_SEQ" AND "A"."UCS_SEQ"="B"."UCS_SEQ")
</p>
<p>
{color}
</p>
<p>
{color:blue}
</p>
<p>
Explain Plan -- 2:
</p>
<p>
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | | | | 3341 (100)| |
|* 1 | HASH JOIN RIGHT OUTER | | 12967 | 2216K| | 3341 (5)| 00:00:41 |
| 2 | VIEW | | 1 | 57 | | 607 (6)| 00:00:08 |
| 3 | HASH GROUP BY | | 1 | 209 | | 607 (6)| 00:00:08 |
|* 4 | FILTER | | | | | | |
|* 5 | TABLE ACCESS BY INDEX ROWID | UCSI_ITEM | 1 | 74 | | 1 (0)| 00:00:01 |
| 6 | NESTED LOOPS | | 1 | 209 | | 606 (6)| 00:00:08 |
| 7 | NESTED LOOPS | | 1 | 135 | | 605 (6)| 00:00:08 |
|* 8 | HASH JOIN | | 1 | 123 | | 604 (6)| 00:00:08 |
|* 9 | TABLE ACCESS BY INDEX ROWID| ULT_CUST_SALE | 1214 | 71626 | | 455 (7)| 00:00:06 |
|* 10 | INDEX SKIP SCAN | XIE1ULT_CUST_SALE | 1 | | | 455 (7)| 00:00:06 |
| 11 | TABLE ACCESS BY INDEX ROWID| ULT_CUST_MASTER | 245 | 12985 | | 17 (0)| 00:00:01 |
| 12 | NESTED LOOPS | | 1971 | 123K| | 148 (2)| 00:00:02 |
|* 13 | TABLE ACCESS FULL | US_STATE_COUNTY | 8 | 88 | | 9 (12)| 00:00:01 |
|* 14 | INDEX RANGE SCAN | TEST | 245 | | | 1 (0)| 00:00:01 |
|* 15 | TABLE ACCESS BY INDEX ROWID | SIC2 | 1 | 12 | | 1 (0)| 00:00:01 |
|* 16 | INDEX UNIQUE SCAN | XPKSIC2 | 1 | | | 1 (0)| 00:00:01 |
|* 17 | INDEX RANGE SCAN | XPKUCSI_ITEM | 1 | | | 1 (0)| 00:00:01 |
| 18 | VIEW | | 12967 | 1494K| | 2732 (5)| 00:00:33 |
| 19 | HASH UNIQUE | | 12967 | 3254K| 6936K| 2732 (5)| 00:00:33 |
|* 20 | HASH JOIN | | 12967 | 3254K| | 1998 (6)| 00:00:24 |
| 21 | VIEW | | 410 | 16400 | | 1781 (5)| 00:00:22 |
| 22 | HASH GROUP BY | | 410 | 13120 | | 1781 (5)| 00:00:22 |
|* 23 | FILTER | | | | | | |
|* 24 | INDEX RANGE SCAN | XIE1ULT_CUST_SALE | 1963K| 59M| | 1781 (5)| 00:00:22 |
|* 25 | HASH JOIN | | 4792 | 1015K| | 215 (7)| 00:00:03 |
|* 26 | TABLE ACCESS FULL | SIC1 | 11 | 528 | | 2 (0)| 00:00:01 |
|* 27 | HASH JOIN | | 4792 | 790K| | 212 (6)| 00:00:03 |
|* 28 | TABLE ACCESS BY INDEX ROWID | CUSTOMER | 1003 | 79237 | | 4 (0)| 00:00:01 |
|* 29 | INDEX RANGE SCAN | XIF317CUSTOMER | 1371 | | | 1 (0)| 00:00:01 |
|* 30 | HASH JOIN | | 4794 | 421K| | 207 (6)| 00:00:03 |
| 31 | TABLE ACCESS BY INDEX ROWID | ULT_CUST_MASTER | 245 | 8820 | | 17 (0)| 00:00:01 |
| 32 | NESTED LOOPS | | 1971 | 136K| | 148 (2)| 00:00:02 |
|* 33 | TABLE ACCESS FULL | US_STATE_COUNTY | 8 | 280 | | 9 (12)| 00:00:01 |
|* 34 | INDEX RANGE SCAN | TEST | 245 | | | 1 (0)| 00:00:01 |
|* 35 | TABLE ACCESS FULL | TURFBUILDER_GROUP2_EMPCNT_TMP | 8914 | 165K| | 58 (14)| 00:00:01 |
Predicate Information (identified by operation id):
1 - access("CUST"."CUST_NUM"="CUST_SALE"."CUST_NUM" AND "CUST"."SIC1"="CUST_SALE"."SIC1")
4 - filter(TO_DATE(:B2,'dd mon yyyy')<=TO_DATE(:B1,'dd mon yyyy'))
5 - filter((("A"."UCSII_UNIT_FG"='Y' OR ("A"."UCSII_ITEM_NUM" LIKE '%.%' AND "A"."UCSII_UNIT_FG"='N')) AND
"A"."UCSII_IN_APMR_FG"='Y' AND INTERNAL_FUNCTION("A"."UCSII_CONTRACT_ID") AND "A"."UCSII_AUDIT_DATA_CD"='G' AND
"A"."REC_STATUS"='A'))
8 - access("C"."DIV_CD"="B"."DIV_CD" AND "C"."CTRY_CD"="B"."CTRY_CD" AND "C"."CUST_NUM"="B"."CUST_NUM" AND
"C"."UCM_MAILBOX_NUM"="B"."UCM_MAILBOX_NUM" AND "C"."UCM_SEQ"="B"."UCM_SEQ")
9 - filter("B"."UA_CD"='ENDCUST')
10 - access("B"."DIV_CD"=:B4 AND "B"."CTRY_CD"=:B3 AND "B"."UCS_DT">=TO_DATE(:B2,'dd mon yyyy') AND
"B"."REC_STATUS"='A' AND "B"."UCS_DT"<=TO_DATE(:B1,'dd mon yyyy'))
filter(("B"."UCS_DT">=TO_DATE(:B2,'dd mon yyyy') AND "B"."REC_STATUS"='A' AND "B"."UCS_DT"<=TO_DATE(:B1,'dd
mon yyyy')))
13 - filter((UPPER("U"."USC_STATE_ABBREV")<>'PR' AND UPPER("U"."USC_STATE_ABBREV")<>'VI' AND "U"."REC_STATUS"='A'))
14 - access("C"."UCM_STCNTY_FIPS_CD"="U"."USC_ST_CNTY_CD" AND "C"."DIV_CD"=:B4 AND "C"."CTRY_CD"=:B3 AND
"C"."REC_STATUS"='A')
15 - filter("SC2"."REC_STATUS"='A')
16 - access("SC2"."SIC2"=SUBSTR("C"."UCM_SIC_CD",1,2))
17 - access("A"."DIV_CD"=:B4 AND "A"."CTRY_CD"=:B3 AND "A"."CUST_NUM"="B"."CUST_NUM" AND
"A"."UCM_MAILBOX_NUM"="B"."UCM_MAILBOX_NUM" AND "A"."UCM_SEQ"="B"."UCM_SEQ" AND "A"."UCS_SEQ"="B"."UCS_SEQ")
20 - access("B"."DIV_CD"="UCM"."DIV_CD" AND "B"."CTRY_CD"="UCM"."CTRY_CD" AND "B"."CUST_NUM"="UCM"."CUST_NUM")
23 - filter((:B3=:B3 AND :B4=:B4))
24 - access("DIV_CD"=:B4 AND "CTRY_CD"=:B3 AND "REC_STATUS"='A')
filter(("DIV_CD"=:B4 AND "CTRY_CD"=:B3 AND "DIV_CD"=:B4 AND "CTRY_CD"=:B3 AND "REC_STATUS"='A'))
25 - access("TET_VM_CODE"="SC1"."SIC1")
26 - filter("SC1"."REC_STATUS"='A')
27 - access("F"."DIV_CD"="UCM"."DIV_CD" AND "F"."CTRY_CD"="UCM"."CTRY_CD" AND "F"."CUST_NUM"="UCM"."CUST_NUM")
28 - filter(("F"."DIV_CD"=:B4 AND "F"."CUST_IMP21_DEALER_FG"='Y' AND NVL("F"."CUST_TEST_DEALER_FG",'N')<>'Y'))
29 - access("F"."CTRY_CD"=:B3)
30 - access("TET_CODE"="UCM"."CUST_NUM")
33 - filter((UPPER("U"."USC_STATE_ABBREV")<>'PR' AND UPPER("U"."USC_STATE_ABBREV")<>'VI' AND "U"."REC_STATUS"='A'))
34 - access("UCM"."UCM_STCNTY_FIPS_CD"="U"."USC_ST_CNTY_CD" AND "UCM"."DIV_CD"=:B4 AND "UCM"."CTRY_CD"=:B3 AND
"UCM"."REC_STATUS"='A')
35 - filter("TET_TYPE"='D')
</p>
<p>
{color}
</p> -
How Can I increase performance of Query with Distinct Keyword
Dear Experts,
In my Query when I execute this without Distinct it give result very soon,
But when I excute this with Distinct its performance is very slow is there any option for increase the performance with Distinct .
I have to use Distinct according to our rewuirement.neither DISTINCT nor GROUP BY do sort. If you need to sort, use ORDER BY. Slight correction, they do a sort, but your results are not guarenteed to be sorted.
The overhead of a sort is incurred, if your results is large enough (my test below isn't) you will be sorting to disk. Which as we all know can be very slow.
9i:
SQL> SET TRIMSPOOL ON
SQL> CREATE TABLE D (A VARCHAR2(2));
Table created.
SQL> INSERT INTO D (A) SELECT DBMS_RANDOM.STRING('U',2) FROM DUAL CONNECT BY LEVEL <= 5000;
5000 rows created.
SQL> COMMIT;
Commit complete.
SQL> SET AUTOTRACE TRACEONLY EXPLAIN;
SQL> SELECT DISTINCT A FROM D;
Execution Plan
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (UNIQUE)
2 1 TABLE ACCESS (FULL) OF 'D'
SQL> SELECT A FROM D GROUP BY A;
Execution Plan
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (GROUP BY)
2 1 TABLE ACCESS (FULL) OF 'D'
SQL> SELECT DISTINCT A FROM D ORDER BY A;
Execution Plan
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (UNIQUE)
2 1 TABLE ACCESS (FULL) OF 'D'
SQL> SPOOL OFF10g
SQL> SET TRIMSPOOL ON
SQL> CREATE TABLE D (A VARCHAR2(2));
Table created.
SQL> INSERT INTO D (A) SELECT DBMS_RANDOM.STRING('U',2) FROM DUAL CONNECT BY LEVEL <= 5000;
5000 rows created.
SQL> COMMIT;
Commit complete.
SQL> SET AUTOTRACE TRACEONLY EXPLAIN;
SQL> SELECT DISTINCT A FROM D;
Execution Plan
Plan hash value: 3079699766
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 5000 | 15000 | 7 (29)| 00:00:01 |
| 1 | HASH UNIQUE | | 5000 | 15000 | 7 (29)| 00:00:01 |
| 2 | TABLE ACCESS FULL| D | 5000 | 15000 | 5 (0)| 00:00:01 |
Note
- dynamic sampling used for this statement
SQL> SELECT A FROM D GROUP BY A;
Execution Plan
Plan hash value: 2712634873
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 5000 | 15000 | 7 (29)| 00:00:01 |
| 1 | HASH GROUP BY | | 5000 | 15000 | 7 (29)| 00:00:01 |
| 2 | TABLE ACCESS FULL| D | 5000 | 15000 | 5 (0)| 00:00:01 |
Note
- dynamic sampling used for this statement
SQL> SELECT DISTINCT A FROM D ORDER BY A;
Execution Plan
Plan hash value: 1773491675
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 5000 | 15000 | 8 (38)| 00:00:01 |
| 1 | SORT UNIQUE | | 5000 | 15000 | 7 (29)| 00:00:01 |
| 2 | TABLE ACCESS FULL| D | 5000 | 15000 | 5 (0)| 00:00:01 |
Note
- dynamic sampling used for this statement
SQL> SPOOL OFF -
hi ,
i am using oracle 10g
i have created as view that has few 100 Ks of records -- long_view
and i have a table with few 100s of records -- small_table
the performance if the long_view is good i.e records are returned fast even though from explain plan , it uses "table access full" for some tables
however , when i join the view to the table , the performance is slow
select distinct a.name from long_view a , small_table b
where a.name = b.namebase tables used by the views have been analyzed
what does this indicate ? my view is not optimal ?
what i dun understand is how come the view by itself is fast but not when linked to another table ?
pls advise
tks & rgdshi ,
1 - my measurement of the performance of the view is it returns records fast and i stopped when it reached close to 100k and it's within a minute
2 here's the explain plan , (i need to dig out how i got the execution plan using tkprof, will take some time)
-- join of view & table
SELECT STATEMENT, GOAL = ALL_ROWS Cost=5576 Cardinality=1 Bytes=150
HASH UNIQUE Cost=5576 Cardinality=1 Bytes=150
HASH JOIN OUTER Cost=5575 Cardinality=1 Bytes=150
NESTED LOOPS OUTER Cost=5506 Cardinality=1 Bytes=142
NESTED LOOPS OUTER Cost=5506 Cardinality=1 Bytes=132
NESTED LOOPS Cost=1872 Cardinality=1 Bytes=119
HASH JOIN Cost=1870 Cardinality=2 Bytes=198
MAT_VIEW ACCESS BY INDEX ROWID Object owner=DA Object name=PI Cost=835 Cardinality=4 Bytes=248
NESTED LOOPS Cost=1672 Cardinality=8 Bytes=608
TABLE ACCESS FULL Object owner=DA Object name=PC Cost=3 Cardinality=2 Bytes=28
INDEX RANGE SCAN Object owner=DA Object name=PI_IDX1 Cost=831 Cardinality=4
MAT_VIEW ACCESS FULL Object owner=DA Object name=PR Cost=198 Cardinality=11170 Bytes=256910
INDEX RANGE SCAN Object owner=DA Object name=GE_IDX1 Cost=1 Cardinality=1 Bytes=20
VIEW PUSHED PREDICATE Object owner=DA Cost=3633 Cardinality=1 Bytes=13
HASH JOIN Cost=3633 Cardinality=19 Bytes=1463
INLIST ITERATOR
MAT_VIEW ACCESS BY INDEX ROWID Object owner=DA Object name=PI Cost=3436 Cardinality=19 Bytes=1064
INDEX RANGE SCAN Object owner=DA Object name=PI_IDX1 Cost=3420 Cardinality=19
MAT_VIEW ACCESS FULL Object owner=DA Object name=PR Cost=196 Cardinality=22341 Bytes=469161
INDEX UNIQUE SCAN Object owner=DA Object name=PST_PK Cost=0 Cardinality=1 Bytes=10
MAT_VIEW ACCESS FULL Object owner=DA Object name=RCP Cost=69 Cardinality=9623 Bytes=76984
-- select * from view itself
SELECT STATEMENT, GOAL = ALL_ROWS Cost=8540 Cardinality=10033 Bytes=20256627
VIEW Object owner=DA Object name=PR_CURR_RVIEW Cost=8540 Cardinality=10033 Bytes=20256627
WINDOW SORT Cost=8540 Cardinality=10033 Bytes=3832606
HASH JOIN RIGHT OUTER Cost=7719 Cardinality=10033 Bytes=3832606
MAT_VIEW ACCESS FULL Object owner=DA Object name=RCP Cost=69 Cardinality=9623 Bytes=740971
HASH JOIN OUTER Cost=7649 Cardinality=8203 Bytes=2501915
HASH JOIN OUTER Cost=3827 Cardinality=832 Bytes=152256
HASH JOIN Cost=3811 Cardinality=832 Bytes=128960
MAT_VIEW ACCESS FULL Object owner=DA Object name=GE Cost=15 Cardinality=776 Bytes=31816
HASH JOIN Cost=3795 Cardinality=30711 Bytes=3501054
MAT_VIEW ACCESS FULL Object owner=DA Object name=PR Cost=198 Cardinality=11170 Bytes=502650
MAT_VIEW ACCESS FULL Object owner=DA Object name=PI Cost=3595 Cardinality=110814 Bytes=7646166
MAT_VIEW ACCESS FULL Object owner=DA Object name=PST Cost=15 Cardinality=3653 Bytes=102284
VIEW Object owner=DA Cost=3818 Cardinality=287470 Bytes=35071340
HASH JOIN Cost=3818 Cardinality=287470 Bytes=21272780
MAT_VIEW ACCESS FULL Object owner=DA Object name=PR Cost=196 Cardinality=22341 Bytes=469161
MAT_VIEW ACCESS FULL Object owner=DA Object name=PI Cost=3613 Cardinality=554069 Bytes=29365657pls advise -
I have the script below and the explain plan
select
leaseid detail_lease,
unit,
bldgid bldgid_A,
bldgname,
orgdesc1,
space_uom,
sum(area) Area
from (
SELECT DECODE (mc.MASTER,
NULL, sl.leaseid,
mc.MASTER
) AS leaseid,
DECODE (SUBSTR (sl.bldgid, 1, 1),
'P', 'PARK',
'SQMTR'
) AS unit,
sl.bldgid, f.flrname,
-- chg 19602 not to show Unassigned area
--NVL (o.orgdesc1, 'Unassigned') AS orgdesc1,
orgdesc1,
-- chg 19602
SUM (DECODE (SUBSTR (sl.bldgid, 1, 1),'P', 1,NVL (Cst_Convert_Uom (s.spuarea,s.uom_std_id,'METR_MTR') * so.PERCENT *.01,0)
) AS area,
DECODE (SUBSTR (sl.bldgid, 1, 1),
'P', 'PARK',
'SQMTR'
) AS space_uom,
NVL (bldg.bldgname, l.lgldesc) AS bldgname
FROM fisinterface.vfis_lease_master_component mc,
space_lease sl,
FLOOR f,
(SELECT spaceorg.bldgid, spaceorg.flrid, spaceorg.spid,
spaceorg.orgid,spaceorg.PERCENT
FROM spaceorg
WHERE TRUNC (SYSDATE) >=
NVL (TRUNC (spaceorg.start_date), TRUNC(SYSDATE) - 1)
AND TRUNC (SYSDATE) <=
NVL (TRUNC (spaceorg.end_date), TRUNC(SYSDATE) + 1)) so,
org o,
lease l,
SPACE s,
vfis_bldg_main_name bldg
WHERE sl.leaseid = mc.component(+)
AND f.bldgid = s.bldgid ||''
AND f.flrid = s.flrid ||''
AND s.bldgid = so.bldgid(+)
AND s.flrid = so.flrid(+)
AND s.spid = so.spid(+)
AND so.orgid = o.orgid(+)
AND s.bldgid = sl.bldgid
AND s.flrid = sl.flrid
AND SUBSTR(S.SPSTATOW,1,1) = 'A'
AND s.spid = sl.spid
AND DECODE (mc.MASTER, NULL, sl.leaseid, mc.MASTER) =
l.leaseid
AND l.ltflag = 'T'
AND s.bldgid = bldg.bldgid(+)
GROUP BY DECODE (mc.MASTER, NULL, sl.leaseid, mc.MASTER),
DECODE (SUBSTR (sl.bldgid, 1, 1), 'P', 'PARK', 'SQMTR'),
sl.bldgid,
f.flrname,
o.orgdesc1,
DECODE (SUBSTR (sl.bldgid, 1, 1), 'P', 'PARK', 'SQMTR'),
NVL (bldg.bldgname, l.lgldesc))
GROUP BY leaseid, unit,bldgid , bldgname, orgdesc1,space_uom
ORDER BY LEASEID ,bldgid, ORGDESC1
EXPLAIN PLAN
Operation Object Name Rows Bytes Cost Object Node In/Out PStart PStop
SELECT STATEMENT Optimizer Mode=ALL_ROWS 87 1562
SORT GROUP BY 87 91 K 1562
VIEW 87 91 K 1561
HASH GROUP BY 87 23 K 1561
HASH JOIN 87 23 K 1560
HASH JOIN 87 21 K 1518
TABLE ACCESS BY INDEX ROWID FAMIS.LEASE 1 K 79 K 62
INDEX RANGE SCAN FAMIS.LEASE_LTFLAG_I 1 K 2
HASH JOIN OUTER 837 153 K 1456
HASH JOIN OUTER 406 63 K 1163
HASH JOIN OUTER 406 55 K 841
NESTED LOOPS OUTER 406 41 K 834
HASH JOIN 406 25 K 529
TABLE ACCESS FULL FAMIS.SPACE 1 K 41 K 467
INDEX FAST FULL SCAN FAMIS.SPACE_LEASE_PK 40 K 1 M 61
TABLE ACCESS BY INDEX ROWID FAMIS.SPACEORG 1 40 1
INDEX RANGE SCAN FAMIS.CST_SPACEORG_BFSPID 1 1
TABLE ACCESS FULL FAMIS.ORG 1 K 46 K 7
VIEW FISINTERFACE.VFIS_LEASE_MASTER_COMPONENT 2 K 39 K 322
HASH UNIQUE 2 K 588 K 322
HASH JOIN 2 K 588 K 188
HASH JOIN 2 K 333 K 112
TABLE ACCESS FULL FAMIS.LEASE 7 K 965 K 76
TABLE ACCESS BY INDEX ROWID FAMIS.BUILDING_JOURNAL 12 K 322 K 292
INDEX RANGE SCAN FAMIS.CST_BUILDING_JOURNAL_TYPE_IX 12 K 37
TABLE ACCESS FULL FAMIS.FLOOR 11 K 285 K 41
The space table has 118488 records and its doing a full table scan. the primary key in this table is BLDGID, FLRID, SPID
vfis_lease_master_component is a view and has 7737 records and a full scan is done.
re_doc_relationship is a view with 10833 and doing a full table scan
lease is a table with 13807 records and a full table can is performed the primary key is lease ID
Floor is a table with 1125 records and it doing a full table scan The primary key is
Bldgid, flrid.
Am using this query in oracle reports and the report is timming out in the browser which is not acceptable to the user. Any help will be greately appreciated.
Thank you.When I first saw this, I thought I would skip my evening SuDoKu and do this SQL instead. Well, in the end I did the SuDoKu and managed only to make the SQL readable.
select leaseid detail_lease
,unit
,bldgid bldgid_A
,bldgname
,orgdesc1
,space_uom
,sum(area) Area
from (SELECT DECODE (mc.MASTER
,NULL, sl.leaseid
,mc.MASTER) AS leaseid
,DECODE (SUBSTR (sl.bldgid, 1, 1)
,'P', 'PARK'
,'SQMTR') AS unit
,sl.bldgid
,f.flrname
,orgdesc1
,SUM (DECODE (SUBSTR (sl.bldgid, 1, 1)
,'P', 1
,NVL (Cst_Convert_Uom (s.spuarea,s.uom_std_id,'METR_MTR') * so.PERCENT *.01,0))) AS area
,DECODE (SUBSTR (sl.bldgid, 1, 1)
,'P', 'PARK'
,'SQMTR') AS space_uom
,NVL (bldg.bldgname, l.lgldesc) AS bldgname
FROM fisinterface.vfis_lease_master_component mc
,space_lease sl
,FLOOR f
,(SELECT spaceorg.bldgid
,spaceorg.flrid
,spaceorg.spid
,spaceorg.orgid
,spaceorg.PERCENT
FROM spaceorg
WHERE TRUNC (SYSDATE) >= NVL (TRUNC (spaceorg.start_date), TRUNC(SYSDATE) - 1)
AND TRUNC (SYSDATE) <= NVL (TRUNC (spaceorg.end_date), TRUNC(SYSDATE) + 1)) so
,org o
,lease l
,SPACE s
,vfis_bldg_main_name bldg
WHERE sl.leaseid = mc.component(+)
AND f.bldgid = s.bldgid ||''
AND f.flrid = s.flrid ||''
AND s.bldgid = so.bldgid(+)
AND s.flrid = so.flrid(+)
AND s.spid = so.spid(+)
AND so.orgid = o.orgid(+)
AND s.bldgid = sl.bldgid
AND s.flrid = sl.flrid
AND s.spid = sl.spid
AND l.ltflag = 'T'
AND s.bldgid = bldg.bldgid(+)
AND SUBSTR(S.SPSTATOW,1,1) = 'A'
AND DECODE (mc.MASTER
,NULL, sl.leaseid
,mc.MASTER) = l.leaseid
GROUP BY DECODE (mc.MASTER
,NULL, sl.leaseid
,mc.MASTER)
,DECODE (SUBSTR (sl.bldgid, 1, 1)
,'P', 'PARK'
,'SQMTR')
,sl.bldgid
,f.flrname
,o.orgdesc1
,DECODE (SUBSTR (sl.bldgid, 1, 1)
,'P', 'PARK'
,'SQMTR')
,NVL (bldg.bldgname, l.lgldesc))
GROUP BY leaseid
,unit
,bldgid
,bldgname
,orgdesc1
,space_uom
ORDER BY LEASEID
,bldgid
,ORGDESC1At first, we have a select with a few columns, group by and order by. No problem... Except, what about the "from"?
This is itself a select with a group by.... Also nothing special.
Only, the inner select is picking data from eight tables, of which one is itself a select, then adding four outer joints.
I think this is where the combination of parser and optimizer is about to give up. No amount of tuning will really solve that problem.
I believe the creators of the database state that one should not join more than five tables in a select.
Maybe a couple of views on some of the data would help?
In my opinion, there has got to be a design issue stuck here somewhere and modifying the select isn't really going to solve that.
Sorry.... My opinion.... Maybe someone else has better advice.... -
VS2005/CR - Certificate check, performance problem
Post Author: Lars-Inge
CA Forum: General
Hello,I have a problem with the Crystal Reports (with CR ServicePack 1 installed) that shipps with the Visual Studio 2005 Professional IDE. It looks like the reports are using a certificate check that is out on the internet(?). The synpthoms are extremely bad performance the first time the reports are instantiated. E.g say I have this C# code: CrystalReport1 rep = new CrystalReport1();The first time this line is called it takes minute(s) (1 minute + 40 sec) before it completes. After it completes the first time, the next calls to this line takes less than nothing (less than 1 sec). I want it to take less than nothing (less than 5-6 sec is OK) the first time aswell.If I disable the certificate check in the registry in Windows, it takes less than 1 second the first time aswell. E.g in "regedit":My ComputerHKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionWinTrustTrusted ProvidersSoftware PublishingChange the "state" from "0x23c00" to "+ "0x23e00" to switch it off.But I cannot do this on a customer computer.Does anyone have any good suggestions, please?Best regards,Lars-IngeHi,
both execution plans have very similar cost values (278461 for the bad plan, 270476 for the good plan) and the necessary I/O is also similar. But the bad plan creates an intermediate result of almost 500M rows before the SORT UNIQUE reduces this result to just 505 rows - while the good plan sorts the input data before doing the join and reduces the 627859 rows before doing a second sort operation (HASH UNIQUE). In addition the Nested Loops join to create the result for the inline-view trt_cells in the first plan seems to be more reasonable than the HASH join in the bad plan - but the treatment of ch_cells seems to be the bigger problem.
With the very similar cost value a small change in the arithemtic can result in a changed plan. But both plans do a bad job to determine the size of the resultsets of the hash joins: the bad plan expects to get 2.3M rows (instead of 500M) before the sort takes place and the good plan shows 1900 rows for the join (and gets 627859 rows).
I would try to check why the cardinalities for the join of ACRM_LEAD_TO_CHANNEL_DAILY and UA_CONTACTHISTORY with the join condition (ch.treatmentcode = daily_leads.treatmentcode) are not accurate. Perhaps the columns statistics for the join columns are misleading (number of distinct values, low_value, high_value in user_tab_cols). You could try to use the values in the standard formulas to calculate join selectivity and cardinality (here in a simplified version from Randolf Geist's blog: Oracle related stuff: Table Functions And Join Cardinality Estimates):
Join Selectivity = 1 / greater(num_distinct(t1.c1), num_distinct(t2.c2))
Join Cardinality = Join Selectivity * cardinality t1 * cardinality t2
Perhaps the results will show where the CBO needs a little bit help (or better statistics).
Regards
Martin -
5 tables Used - Performance Improvement Help Req...
Hello Experts,
I am using 5 table joins to fetch data from query; does this will degrade performance?
Please find below the query used; in this WHERE Clause, 1) le.locker_entry_id is PRIMARY Key column
2) dc.object_type - created a index on this column 3) Created a function based index on this column upper(dt.partner_device_type)
Can any other code improvement be done or view be created ?
Please suggest.
SELECT count(*) FROM locker_entry le;
COUNT(*)
1762
SELECT count(*) FROM digital_compatibility dc;
COUNT(*)
227757
SELECT count(*) FROM digital_encode_profile dep;
COUNT(*)
48
SELECT count(*) FROM device_type dt;
COUNT(*)
421
SELECT count(*) FROM digital_sku dsku;
COUNT(*)
26037
EXPLAIN PLAN FOR
SELECT
/*+ INDEX(dep, DIGITAL_ENCODE_PROFILE_ID_PK) */
DISTINCT le.locker_entry_id AS locker_entry_id,
dep.delivery_type
FROM locker_entry le,
digital_compatibility dc,
digital_encode_profile dep,
device_type dt,
digital_sku dsku
WHERE le.sku_id = dsku.legacy_id
AND le.digital_package_id = dsku.digital_package_id
AND dsku.digital_sku_id = dc.object_id
AND dc.encode_profile_id =dep.digital_encode_profile_id
AND dt.capability_set_id =dc.capability_set_id
AND le.locker_entry_id IN (:1, :2, :3, :4, :5, :6, :7, :8, :9, :10, :11, :12, :13, :14, :15, :16, :17, :18, :19, :20, :21, :22, :23, :24, :25, :26, :27, :28, :29, :30, :31, :32)
AND dc.object_type =:"SYS_B_0"
AND upper(dt.partner_device_type) =:33;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
| 0 | SELECT STATEMENT | | 1 | 370 | 481 (3)|
| 1 | HASH UNIQUE | | 1 | 370 | 481 (3)|
| 2 | NESTED LOOPS | | 1 | 370 | 480 (3)|
| 3 | NESTED LOOPS | | 1 | 336 | 479 (3)|
|* 4 | HASH JOIN | | 1 | 193 | 478 (3)|
| 5 | MAT_VIEW ACCESS BY INDEX ROWID | DIGITAL_SKU | 1 | 48 | 5 (0)|
| 6 | NESTED LOOPS | | 16 | 1392 | 5 (0)|
| 7 | INLIST ITERATOR | | | | |
| 8 | TABLE ACCESS BY INDEX ROWID | LOCKER_ENTRY | 32 | 1248 | 1 (0)|
|* 9 | INDEX RANGE SCAN | LOCKER_ENTRY_ID_PK | 32 | | 1 (0)|
| 10 | BITMAP CONVERSION TO ROWIDS | | | | |
| 11 | BITMAP AND | | | | |
| 12 | BITMAP CONVERSION FROM ROWIDS| | | | |
|* 13 | INDEX RANGE SCAN | IDX_DIGITAL_SKU_LEGACY_ID | 1 | | 1 (0)|
| 14 | BITMAP CONVERSION FROM ROWIDS| | | | |
|* 15 | INDEX RANGE SCAN | IDX_DIGITAL_PACKAGE_ID | 1 | | 1 (0)|
|* 16 | MAT_VIEW ACCESS FULL | DIGITAL_COMPATIBILITY | 2098 | 217K| 472 (3)|
|* 17 | INDEX RANGE SCAN | DEVICE_TYPE_IDX | 1 | 143 | 1 (0)|
| 18 | MAT_VIEW ACCESS BY INDEX ROWID | DIGITAL_ENCODE_PROFILE | 1 | 34 | 1 (0)|
|* 19 | INDEX UNIQUE SCAN | DIGITAL_ENCODE_PROFILE_ID_PK | 1 | | 1 (0)|
Predicate Information (identified by operation id):
4 - access("DSKU"."DIGITAL_SKU_ID"=TO_NUMBER("DC"."OBJECT_ID"))
9 - access("LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:1) OR "LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:2) OR
"LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:3) OR "LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:4) OR
"LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:5) OR "LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:6) OR
"LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:7) OR "LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:8) OR
"LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:9) OR "LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:10) OR
"LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:11) OR "LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:12) OR
"LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:13) OR "LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:14) OR
"LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:15) OR "LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:16) OR
"LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:17) OR "LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:18) OR
"LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:19) OR "LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:20) OR
"LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:21) OR "LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:22) OR
"LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:23) OR "LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:24) OR
"LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:25) OR "LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:26) OR
"LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:27) OR "LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:28) OR
"LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:29) OR "LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:30) OR
"LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:31) OR "LE"."LOCKER_ENTRY_ID"=TO_NUMBER(:32))
13 - access("LE"."SKU_ID"="DSKU"."LEGACY_ID")
15 - access("LE"."DIGITAL_PACKAGE_ID"="DSKU"."DIGITAL_PACKAGE_ID")
16 - filter("DC"."OBJECT_TYPE"=:SYS_B_0)
17 - access("DT"."CAPABILITY_SET_ID"="DC"."CAPABILITY_SET_ID" AND
UPPER("PARTNER_DEVICE_TYPE")=:33)
19 - access("DC"."ENCODE_PROFILE_ID"="DEP"."DIGITAL_ENCODE_PROFILE_ID")
Note
- 'PLAN_TABLE' is old version
Trace information
=================
recursive calls 17
db block gets 0
consistent gets 239
physical reads 61
redo size 0
bytes sent via SQL*Net to client 742
bytes received via SQL*Net from client 1361
SQL*Net roundtrips to/from client 2
sorts (memory) 5
sorts (disk) 0
Edited by: Linus on Oct 10, 2011 2:44 AMLinus wrote:
Yes Bravid i got regarding the point to remove the hint from the query; unless there is a change in execution plan with index hint.
My concern is; is there any issues by keeping 5 tables on single query and will this degrade performance?
Because as of during the certification practise; i used to overcome some where ,"NOT to use many table joins".
So that is reason i am asking you; sorry if am wrong in any ways.
Thanks...There's nothing inherently wrong with joining lots of tables and there isn't one specific thing that will degrade performance. You could have a query that joins 2 tables performing very badly and a query with 10 tables that performs very well. A lot of it is down to the quality of the decisions the optimiser can make. To get the best decisions out of it you need to make sure it had enough information to work with. So that means making sure stats are available and relevant for the data you're querying and removing any hints unless you have a specific reason to use them.
Earlier this year I had the "joy" of working with a query that had 65 tables in it. It was an INSERT INTO...SELECT FROM and it was a clear example of where a single statement really should have been about 6 or 7 separate statements. The reason in this case was because there were 6 or 7 different sections to the query that had essentially no relationship with each other and they were all outer joined and used lots of analytic functions and case statements to categorise each row and populate the same columns with different values depending on which query block it had originated from.
This is an extreme example but the point is you have to look at the statement and decide whether it does it's job well. My personal preference is to try to avoid big "generic" SQL statements that cater for lots of different scenarios because they can easily become over complicated and difficult to maintain and tune.
HTH
David
Edited by: Bravid on Oct 10, 2011 1:53 PM -
hello every one,
This is rahul
when we are declaring internal table by default it takes as standard table
but y don't we take hashed table they can get performance very well
hashed can perform very well than standard nahI
READ THIS POINTS
Internal tables are the core of ABAP. They are like soul of a body. For any program we use
internal tables extensively. We can use Internal tables like normal data base tables only, but the
basic difference is the memory allocated for internal tables is temporary. Once the program is
closed the memory allocated for internal tables will also be out of memory.
But while using the internal tables, there are many performance issues to be considered. i.e which
type of internal table to be used for the program..like standard internal table, hashed internal
table or sorted internal table etc..
Internal tables
Internal tables provide a means of taking data from a fixed structure and storing it in working memory in ABAP. The data is stored line by
line in memory, and each line has the same structure. In ABAP, internal tables fulfill the function of arrays. Since they are dynamic data
objects, they save the programmer the task of dynamic memory management in his or her programs. You should use internal tables
whenever you want to process a dataset with a fixed structure within a program. A particularly important use for internal tables is for
storing and formatting data from a database table within a program. They are also a good way of including very complicated data
structures in an ABAP program.
Like all elements in the ABAP type concept, internal tables can exist both as data types and as data objects A data type is the abstract
description of an internal table, either in a program or centrally in the ABAP Dictionary, that you use to create a concrete data object. The
data type is also an attribute of an existing data object.
Internal Tables as Data Types
Internal tables and structures are the two structured data types in ABAP. The data type of an internal table is fully specified by its line type,
key, and table type.
Line type
The line type of an internal table can be any data type. The data type of an internal table is normally a structure. Each component of the
structure is a column in the internal table. However, the line type may also be elementary or another internal table.
Key
The key identifies table rows. There are two kinds of key for internal tables - the standard key and a user-defined key. You can specify
whether the key should be UNIQUE or NON-UNIQUE. Internal tables with a unique key cannot contain duplicate entries. The uniqueness
depends on the table access method.
If a table has a structured line type, its default key consists of all of its non-numerical columns that are not references or themselves
internal tables. If a table has an elementary line type, the default key is the entire line. The default key of an internal table whose line type
is an internal table, the default key is empty.
The user-defined key can contain any columns of the internal table that are not references or themselves internal tables. Internal tables
with a user-defined key are called key tables. When you define the key, the sequence of the key fields is significant. You should remember
this, for example, if you intend to sort the table according to the key.
Table type
The table type determines how ABAP will access individual table entries. Internal tables can be divided into three types:
Standard tables have an internal linear index. From a particular size upwards, the indexes of internal tables are administered as trees. In
this case, the index administration overhead increases in logarithmic and not linear relation to the number of lines. The system can access
records either by using the table index or the key. The response time for key access is proportional to the number of entries in the table.
The key of a standard table is always non-unique. You cannot specify a unique key. This means that standard tables can always be filled
very quickly, since the system does not have to check whether there are already existing entries.
Sorted tables are always saved sorted by the key. They also have an internal index. The system can access records either by using the
table index or the key. The response time for key access is logarithmically proportional to the number of table entries, since the system
uses a binary search. The key of a sorted table can be either unique or non-unique. When you define the table, you must specify whether
the key is to be unique or not. Standard tables and sorted tables are known generically as index tables.
Hashed tables have no linear index. You can only access a hashed table using its key. The response time is independent of the number of
table entries, and is constant, since the system access the table entries using a hash algorithm. The key of a hashed table must be unique.
When you define the table, you must specify the key as UNIQUE.
Generic Internal Tables
Unlike other local data types in programs, you do not have to specify the data type of an internal table fully. Instead, you can specify a
generic construction, that is, the key or key and line type of an internal table data type may remain unspecified. You can use generic
internal tables to specify the types of field symbols and the interface parameters of procedures . You cannot use them to declare data
objects.
Internal Tables as Dynamic Data Objects
Data objects that are defined either with the data type of an internal table, or directly as an internal table, are always fully defined in
respect of their line type, key and access method. However, the number of lines is not fixed. Thus internal tables are dynamic data objects,
since they can contain any number of lines of a particular type. The only restriction on the number of lines an internal table may contain are
the limits of your system installation. The maximum memory that can be occupied by an internal table (including its internal administration)
is 2 gigabytes. A more realistic figure is up to 500 megabytes. An additional restriction for hashed tables is that they may not contain more
than 2 million entries. The line types of internal tables can be any ABAP data types - elementary, structured, or internal tables. The
individual lines of an internal table are called table lines or table entries. Each component of a structured line is called a column in the
internal table.
Choosing a Table Type
The table type (and particularly the access method) that you will use depends on how the typical internal table operations will be most
frequently executed.
Standard tables
This is the most appropriate type if you are going to address the individual table entries using the index. Index access is the quickest
possible access. You should fill a standard table by appending lines (ABAP APPEND statement), and read, modify and delete entries by
specifying the index (INDEX option with the relevant ABAP command). The access time for a standard table increases in a linear relationship
with the number of table entries. If you need key access, standard tables are particularly useful if you can fill and process the table in
separate steps. For example, you could fill the table by appending entries, and then sort it. If you use the binary search option with key
access, the response time is logarithmically proportional to the number of table entries.
Sorted tables
This is the most appropriate type if you need a table which is sorted as you fill it. You fill sorted tables using the INSERT statement. Entries
are inserted according to the sort sequence defined through the table key. Any illegal entries are recognized as soon as you try to add
them to the table. The response time for key access is logarithmically proportional to the number of table entries, since the system always
uses a binary search. Sorted tables are particularly useful for partially sequential processing in a LOOP if you specify the beginning of the
table key in the WHERE condition.
Hashed tables
This is the most appropriate type for any table where the main operation is key access. You cannot access a hashed table using its index.
The response time for key access remains constant, regardless of the number of table entries. Like database tables, hashed tables always
have a unique key. Hashed tables are useful if you want to construct and use an internal table which resembles a database table or for
processing large amounts of data.
Creating Internal Tables
Like other elements in the ABAP type concept, you can declare internal tables as abstract data
types in programs or in the ABAP Dictionary, and then use them to define data objects.
Alternatively, you can define them directly as data objects. When you create an internal table as a
data object, you should ensure that only the administration entry which belongs to an internal
table is declared statically. The minimum size of an internal table is 256 bytes. This is important if an
internal table occurs as a component of an aggregated data object, since even empty internal
tables within tables can lead to high memory usage. (In the next functional release, the size of the
table header for an initial table will be reduced to 8 bytes). Unlike all other ABAP data objects, you
do not have to specify the memory required for an internal table. Table rows are added to and
deleted from the table dynamically at runtime by the various statements for adding and deleting
records.
You can create internal tables in different types.
You can create standard internal table and then make it sort in side the program.
The same way you can change to hashed internal tables also.
There will be some performance issues with regard to standard internal tables/ hashed internal
tables/ sorted internal tables.
Internal table types
This section describes how to define internal tables locally in a program. You can also define internal tables globally as data types in the
ABAP Dictionary.
Like all local data types in programs , you define internal tables using the TYPES statement. If you do not refer to an existing table type
using the TYPE or LIKE addition, you can use the TYPES statement to construct a new local internal table in your program.
TYPES <t> TYPE|LIKE <tabkind> OF <linetype> [WITH <key>]
[INITIAL SIZE <n>].
After TYPE or LIKE, there is no reference to an existing data type. Instead, the type constructor occurs:
<tabkind> OF <linetype> [WITH <key>]
The type constructor defines the table type <tabkind>, the line type <linetype>, and the key <key> of the internal table <t>.
You can, if you wish, allocate an initial amount of memory to the internal table using the INITIAL SIZE addition.
Table type
You can specify the table type <tabkind> as follows:
Generic table types
INDEX TABLE
For creating a generic table type with index access.
ANY TABLE
For creating a fully-generic table type.
Data types defined using generic types can currently only be used for field symbols and for interface parameters in procedures . The generic
type INDEX TABLE includes standard tables and sorted tables. These are the two table types for which index access is allowed. You cannot
pass hashed tables to field symbols or interface parameters defined in this way. The generic type ANY TABLE can represent any table. You
can pass tables of all three types to field symbols and interface parameters defined in this way. However, these field symbols and
parameters will then only allow operations that are possible for all tables, that is, index operations are not allowed.
Fully-Specified Table Types
STANDARD TABLE or TABLE
For creating standard tables.
SORTED TABLE
For creating sorted tables.
HASHED TABLE
For creating hashed tables.
Fully-specified table types determine how the system will access the entries in the table in key operations. It uses a linear search for
standard tables, a binary search for sorted tables, and a search using a hash algorithm for hashed tables.
Line type
For the line type <linetype>, you can specify:
Any data type if you are using the TYPE addition. This can be a predefined ABAP type, a local type in the program, or a data type from the
ABAP Dictionary. If you specify any of the generic elementary types C, N, P, or X, any attributes that you fail to specify (field length, number
of decimal places) are automatically filled with the default values. You cannot specify any other generic types.
Any data object recognized within the program at that point if you are using the LIKE addition. The line type adopts the fully-specified data
type of the data object to which you refer. Except for within classes, you can still use the LIKE addition to refer to database tables and
structures in the ABAP Dictionary (for compatibility reasons).
All of the lines in the internal table have the fully-specified technical attributes of the specified data type.
Key
You can specify the key <key> of an internal table as follows:
[UNIQUE|NON-UNIQUE] KEY <col1> ... <col n>
In tables with a structured line type, all of the components <coli> belong to the key as long as they are not internal tables or references,
and do not contain internal tables or references. Key fields can be nested structures. The substructures are expanded component by
component when you access the table using the key. The system follows the sequence of the key fields.
[UNIQUE|NON-UNIQUE] KEY TABLE LINE
If a table has an elementary line type (C, D, F, I, N, P, T, X), you can define the entire line as the key. If you try this for a table whose line
type is itself a table, a syntax error occurs. If a table has a structured line type, it is possible to specify the entire line as the key. However,
you should remember that this is often not suitable.
[UNIQUE|NON-UNIQUE] DEFAULT KEY
This declares the fields of the default key as the key fields. If the table has a structured line type, the default key contains all non-numeric
columns of the internal table that are not and do not contain references or internal tables. If the table has an elementary line type, the
default key is the entire line. The default key of an internal table whose line type is an internal table, the default key is empty.
Specifying a key is optional. If you do not specify a key, the system defines a table type with an arbitrary key. You can only use this to
define the types of field symbols and the interface parameters of procedures . For exceptions, refer to Special Features of Standard Tables.
The optional additions UNIQUE or NON-UNIQUE determine whether the key is to be unique or non-unique, that is, whether the table can
accept duplicate entries. If you do not specify UNIQUE or NON-UNIQUE for the key, the table type is generic in this respect. As such, it can
only be used for specifying types. When you specify the table type simultaneously, you must note the following restrictions:
You cannot use the UNIQUE addition for standard tables. The system always generates the NON-UNIQUE addition automatically.
You must always specify the UNIQUE option when you create a hashed table.
Initial Memory Requirement
You can specify the initial amount of main memory assigned to an internal table object when you define the data type using the following
addition:
INITIAL SIZE <n>
This size does not belong to the data type of the internal table, and does not affect the type check. You can use the above addition to
reserve memory space for <n> table lines when you declare the table object.
When this initial area is full, the system makes twice as much extra space available up to a limit of 8KB. Further memory areas of 12KB each
are then allocated.
You can usually leave it to the system to work out the initial memory requirement. The first time you fill the table, little memory is used. The
space occupied, depending on the line width, is 16 <= <n> <= 100.
It only makes sense to specify a concrete value of <n> if you can specify a precise number of table entries when you create the table and
need to allocate exactly that amount of memory (exception: Appending table lines to ranked lists). This can be particularly important for
deep-structured internal tables where the inner table only has a few entries (less than 5, for example).
To avoid excessive requests for memory, large values of <n> are treated as follows: The largest possible value of <n> is 8KB divided by the
length of the line. If you specify a larger value of <n>, the system calculates a new value so that n times the line width is around 12KB.
Examples
TYPES: BEGIN OF LINE,
COLUMN1 TYPE I,
COLUMN2 TYPE I,
COLUMN3 TYPE I,
END OF LINE.
TYPES ITAB TYPE SORTED TABLE OF LINE WITH UNIQUE KEY COLUMN1.
The program defines a table type ITAB. It is a sorted table, with line type of the structure LINE and a unique key of the component
COLUMN1.
TYPES VECTOR TYPE HASHED TABLE OF I WITH UNIQUE KEY TABLE LINE.
TYPES: BEGIN OF LINE,
COLUMN1 TYPE I,
COLUMN2 TYPE I,
COLUMN3 TYPE I,
END OF LINE.
TYPES ITAB TYPE SORTED TABLE OF LINE WITH UNIQUE KEY COLUMN1.
TYPES: BEGIN OF DEEPLINE,
FIELD TYPE C,
TABLE1 TYPE VECTOR,
TABLE2 TYPE ITAB,
END OF DEEPLINE.
TYPES DEEPTABLE TYPE STANDARD TABLE OF DEEPLINE
WITH DEFAULT KEY.
The program defines a table type VECTOR with type hashed table, the elementary line type I and a unique key of the entire table line. The
second table type is the same as in the previous example. The structure DEEPLINE contains the internal table as a component. The table
type DEEPTABLE has the line type DEEPLINE. Therefore, the elements of this internal table are themselves internal tables. The key is the
default key - in this case the column FIELD. The key is non-unique, since the table is a standard table.
Internal table objects
Internal tables are dynamic variable data objects. Like all variables, you declare them using the DATA statement. You can also declare static
internal tables in procedures using the STATICS statement, and static internal tables in classes using the CLASS-DATA statement. This
description is restricted to the DATA statement. However, it applies equally to the STATICS and CLASS-DATA statements.
Reference to Declared Internal Table Types
Like all other data objects, you can declare internal table objects using the LIKE or TYPE addition of the DATA statement.
DATA <itab> TYPE <type>|LIKE <obj> [WITH HEADER LINE].
Here, the LIKE addition refers to an existing table object in the same program. The TYPE addition can refer to an internal type in the
program declared using the TYPES statement, or a table type in the ABAP Dictionary.
You must ensure that you only refer to tables that are fully typed. Referring to generic table types (ANY TABLE, INDEX TABLE) or not
specifying the key fully is not allowed (for exceptions, refer to Special Features of Standard Tables).
The optional addition WITH HEADER line declares an extra data object with the same name and line type as the internal table. This data
object is known as the header line of the internal table. You use it as a work area when working with the internal table (see Using the
Header Line as a Work Area). When you use internal tables with header lines, you must remember that the header line and the body of the
table have the same name. If you have an internal table with header line and you want to address the body of the table, you must indicate
this by placing brackets after the table name (<itab>[]). Otherwise, ABAP interprets the name as the name of the header line and not of the
body of the table. You can avoid this potential confusion by using internal tables without header lines. In particular, internal tables nested
in structures or other internal tables must not have a header line, since this can lead to ambiguous expressions.
TYPES VECTOR TYPE SORTED TABLE OF I WITH UNIQUE KEY TABLE LINE.
DATA: ITAB TYPE VECTOR,
JTAB LIKE ITAB WITH HEADER LINE.
MOVE ITAB TO JTAB. <- Syntax error!
MOVE ITAB TO JTAB[].
The table object ITAB is created with reference to the table type VECTOR. The table object JTAB has the same data type as ITAB. JTAB also
has a header line. In the first MOVE statement, JTAB addresses the header line. Since this has the data type I, and the table type of ITAB
cannot be converted into an elementary type, the MOVE statement causes a syntax error. The second MOVE statement is correct, since
both operands are table objects.
Declaring New Internal Tables
You can use the DATA statement to construct new internal tables as well as using the LIKE or TYPE addition to refer to existing types or
objects. The table type that you construct does not exist in its own right; instead, it is only an attribute of the table object. You can refer to
it using the LIKE addition, but not using TYPE. The syntax for constructing a table object in the DATA statement is similar to that for defining
a table type in the TYPES statement.
DATA <itab> TYPE|LIKE <tabkind> OF <linetype> WITH <key>
[INITIAL SIZE <n>]
[WITH HEADER LINE].
As when you define a table type , the type constructor
<tabkind> OF <linetype> WITH <key>
defines the table type <tabkind>, the line type <linekind>, and the key <key> of the internal table <itab>. Since the technical attributes of
data objects are always fully specified, the table must be fully specified in the DATA statement. You cannot create generic table types (ANY
TABLE, INDEX TABLE), only fully-typed tables (STANDARD TABLE, SORTED TABLE, HASHED TABLE). You must also specify the key and whether
it is to be unique (for exceptions, refer to Special Features of Standard Tables).
As in the TYPES statement, you can, if you wish, allocate an initial amount of memory to the internal table using the INITIAL SIZE addition.
You can create an internal table with a header line using the WITH HEADER LINE addition. The header line is created under the same
conditions as apply when you refer to an existing table type.
DATA ITAB TYPE HASHED TABLE OF SPFLI
WITH UNIQUE KEY CARRID CONNID.
The table object ITAB has the type hashed table, a line type corresponding to the flat structure SPFLI from the ABAP Dictionary, and a
unique key with the key fields CARRID and CONNID. The internal table ITAB can be regarded as an internal template for the database table
SPFLI. It is therefore particularly suitable for working with data from this database table as long as you only access it using the key.
Maybe you are looking for
-
Cannot Open Elements 10 after closing it
I installed Elements 10 (Costco version) today. My operating system is Windows 7. After installing, I opened the program and moved around it and tried different things to see how it works. I then closed it. About 15 minutes later, I tried to reop
-
Backslash / pipe bootcamp with Windows 7 (french keyb. - clavier français)
Hello, I bring you the result of search on various forums in the hope of using the backslash and pipe characters of my Macbook Pro 13" french keyboard in Windows 7 with bootcamp 3.2 Here we go : - Backslash: Right ALT + 8 /! - Pipe: Right ALT + 6 § S
-
i wrote a assignment of almost 2500 words in the microsoft word 97-2003 doc but by mistake replace a table only in same name . how can i retain my orinal file which was as Basel III and Banking law
-
Need to reset security questions i kmow what i typed and they are not working
need to know how to reset security questions
-
Dear sir, i am facing problem in background job. we have scheduled MRP run in background. Background job is in "on Hold " and status "ARFC". The job is running in "Active" mode for 11 hours. please give me the suggestions with your experience regar