Question on optimum choice of index - whether to use CTXCAT or CONTEXT
Hi ,
I have a situation in which there are short texts that are to be searched for diacritical characters and for that I implemented CTXCAT type of index. The solution works fine except for left side wild card search - in that case I have suggested the developers to use the query template feature. -this is the background information for the question I have and following example demonstrates it:
CREATE TABLE TEST_USER
FIRST_NAME VARCHAR2(64 CHAR) NOT NULL,
LAST_NAME VARCHAR2(64 CHAR) NOT NULL
CREATE INDEX TEST_USER_IDX3 ON TEST_USER
(FIRST_NAME)
INDEXTYPE IS CTXSYS.CTXCAT
PARAMETERS('LEXER cust_lexer');
CREATE INDEX TEST_USER_IDX4 ON TEST_USER
(LAST_NAME)
INDEXTYPE IS CTXSYS.CTXCAT
PARAMETERS('LEXER cust_lexer');
Don't worry about the cust_lexer, it is for diacritical search and it is not relevant to this question so I am not copying the code for the preference I created etc.
Now I have a row of data in the table with first_name column as Supervisor. If I run the below sql, it gives output:
SELECT *
FROM test_user
WHERE catsearch (first_name, 'Supervisor', NULL) > 0;
FIRST_NAME LAST_NAME
Supervisor upervisor
--even the below sql with wild card (*) at the end works fine...
SQL> SELECT *
2 FROM test_user
3 WHERE catsearch (first_name, 'Super*', NULL) > 0;
FIRST_NAME LAST_NAME
Supervisor upervisor
However the below sql queries doesn't give any output, though they should return the same row as above!
SQL> SELECT *
2 FROM test_user
3 WHERE catsearch (first_name, '*visor', NULL) > 0;
no rows selected
SQL> SELECT *
2 FROM test_user
3 WHERE catsearch (first_name, '*vis*', NULL) > 0;
no rows selected
--Using query template as below solves the issue:
select * from test_user
where catsearch(first_name,
'<query>
<textquery grammar="context">
%viso%
</textquery>
</query>','')>0
FIRST_NAME LAST_NAME
Supervisor upervisor
Note that I verified the query execution plan and it uses the index and there is no Full Table Scan:
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | | | 9 (100)| |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST_USER | 376 | 99K| 9 (0)| 00:00:01 |
|* 2 | DOMAIN INDEX | TEST_USER_IDX3 | | | | |
---------------------------------------------------------------------------------------------- Up to the above , all details were by way of the back ground...now the question is - it is this the right choice? I am using context grammer using query template. There is another thread on this forum where an expert (Barbara) said that
". It should be better to use a context index than a ctxcat index with a query template that uses context grammar. " -this was said on this question link: Re: Wildcard Search
So I am getting this doubt. However I have good data here that shows that the query doesn't do full table scan - still is it a bad choice? Note that there are several issues with CONTENT type of indexes( as per my limited understanding) - because they are not transactional in nature and so we have to take extra steps/measures to have the indexes updated which seems like a major pain area to me.
My doubt is , did I do the right thing by using query template or should I use the CONTEXT type of index instead of CTXCAT type of index?
Thanks,
Nirav
Edited by: orausern on Jan 17, 2013 1:40 AM
Edited by: orausern on Jan 17, 2013 1:43 AM
I would just like to add a few comments.
Alhough it is documented that the ctxcxat index and catsearch do not support a wildcard in front of the term, a workaround is to use two asterisks on the left side of the term, as demonstrated below. I provide this only for clarification and interesting trivia. I would still use a context index for various reasons.
SCOTT@orcl_11gR2> CREATE TABLE TEST_USER
2 (FIRST_NAME VARCHAR2(64 CHAR))
3 /
Table created.
SCOTT@orcl_11gR2> INSERT INTO test_user VALUES ('Supervisor')
2 /
1 row created.
SCOTT@orcl_11gR2> CREATE INDEX TEST_USER_IDX
2 ON TEST_USER (FIRST_NAME)
3 INDEXTYPE IS CTXSYS.CTXCAT
4 /
Index created.
SCOTT@orcl_11gR2> SET AUTOTRACE ON EXPLAIN
SCOTT@orcl_11gR2> SELECT * FROM test_user
2 WHERE catsearch (first_name, '**vis*', NULL) > 0
3 /
FIRST_NAME
Supervisor
1 row selected.
Execution Plan
Plan hash value: 4046491764
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 142 | 3 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST_USER | 1 | 142 | 3 (0)| 00:00:01 |
|* 2 | DOMAIN INDEX | TEST_USER_IDX | | | | |
Predicate Information (identified by operation id):
2 - access("CTXSYS"."CATSEARCH"("FIRST_NAME",'**vis*',NULL)>0)
Note
- dynamic sampling used for this statement (level=2)
SCOTT@orcl_11gR2>The only time that I am aware of that there is a conflict between a wordlist and a lexer is when you specify stemming in both. If you are using stemming, you can still use both a wordlist and a lexer, but only set the stemmer attribute in the wordlist, not the index_stems attribute in the lexer.
Similar Messages
-
Perf issue : wrong choice of index
Hi,
I'm on 10.2.0.4, AIX5.3
Statistics have been gathered, they are up-to-date.
I have a query which run for several hours, here is the query :
UPDATE ps_AB_PDI_CN_TAO_TMP
SET country_2char = COALESCE((
SELECT c.COUNTRY_2CHAR
FROM PSOPRDEFN o
, PS_JOB j
, PS_LOCATION_TBL l
, PS_COUNTRY_TBL c
WHERE j.EMPLID = o.EMPLID
AND j.EFFDT = (SELECT MAX(j1.EFFDT)
FROM PS_JOB j1
WHERE j1.EMPLID = j.EMPLID
AND j1.EMPL_RCD = j.EMPL_RCD
AND j1.EFFDT <= sysdate)
AND j.EFFSEQ = (SELECT MAX(j2.EFFSEQ)
FROM PS_JOB j2
WHERE j2.EMPLID = j.EMPLID
AND j2.EMPL_RCD = j.EMPL_RCD
AND j2.EFFDT = j.EFFDT)
AND j.EMPL_RCD = (SELECT MAX(js.EMPL_RCD)
FROM PS_JOB js
WHERE js.EMPLID = j.EMPLID
AND js.EFFDT = (SELECT MAX(js1.EFFDT)
FROM PS_JOB js1
WHERE js1.EMPLID = js.EMPLID
AND js1.EMPL_RCD = js.EMPL_RCD
AND js1.EFFDT <= sysdate)
AND js.EFFSEQ = (SELECT MAX(js2.EFFSEQ)
FROM PS_JOB js2
WHERE js2.EMPLID = js.EMPLID
AND js2.EMPL_RCD = js.EMPL_RCD
AND js2.EFFDT = js.EFFDT))
AND l.SETID = j.SETID_LOCATION
AND l.LOCATION = j.LOCATION
AND l.EFFDT = (SELECT MAX(l1.EFFDT)
FROM PS_LOCATION_TBL l1
WHERE l1.SETID = l.SETID
AND l1.LOCATION = l.LOCATION
AND l1.EFFDT <= j.EFFDT)
AND l.EFF_STATUS = 'A'
AND c.COUNTRY = l.COUNTRY
AND o.oprid = ps_AB_PDI_CN_TAO_TMP.OPRID),' ' )
WHERE COUNTRY_2CHAR = ' ';Explain plan is the following :
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | UPDATE STATEMENT | | 1 | 52 | 45 (3)| 00:00:01 |
| 1 | UPDATE | PS_AB_PDI_CN_TAO_TMP | | | | |
|* 2 | TABLE ACCESS FULL | PS_AB_PDI_CN_TAO_TMP | 1 | 52 | 45 (3)| 00:00:01 |
| 3 | NESTED LOOPS | | 1 | 80 | 8 (0)| 00:00:01 |
| 4 | NESTED LOOPS | | 1 | 73 | 7 (0)| 00:00:01 |
| 5 | NESTED LOOPS | | 1 | 48 | 5 (0)| 00:00:01 |
| 6 | TABLE ACCESS BY INDEX ROWID | PSOPRDEFN | 1 | 15 | 2 (0)| 00:00:01 |
|* 7 | INDEX UNIQUE SCAN | PS_PSOPRDEFN | 1 | | 1 (0)| 00:00:01 |
| 8 | TABLE ACCESS BY INDEX ROWID | PS_JOB | 1 | 33 | 3 (0)| 00:00:01 |
|* 9 | INDEX RANGE SCAN | PS_JOB | 1 | | 2 (0)| 00:00:01 |
| 10 | SORT AGGREGATE | | 1 | 19 | | |
| 11 | FIRST ROW | | 14 | 266 | 3 (0)| 00:00:01 |
|* 12 | INDEX RANGE SCAN (MIN/MAX) | PSAJOB | 14 | 266 | 3 (0)| 00:00:01 |
| 13 | SORT AGGREGATE | | 1 | 22 | | |
| 14 | FIRST ROW | | 1 | 22 | 3 (0)| 00:00:01 |
|* 15 | INDEX RANGE SCAN (MIN/MAX) | PSAJOB | 1 | 22 | 3 (0)| 00:00:01 |
| 16 | SORT AGGREGATE | | 1 | 22 | | |
| 17 | FIRST ROW | | 1 | 22 | 7 (58)| 00:00:01 |
|* 18 | INDEX FULL SCAN (MIN/MAX) | PSIJOB | 1 | 22 | 7 (58)| 00:00:01 |
| 19 | SORT AGGREGATE | | 1 | 19 | | |
| 20 | FIRST ROW | | 14 | 266 | 3 (0)| 00:00:01 |
|* 21 | INDEX RANGE SCAN (MIN/MAX) | PSAJOB | 14 | 266 | 3 (0)| 00:00:01 |
| 22 | SORT AGGREGATE | | 1 | 22 | | |
| 23 | FIRST ROW | | 1 | 22 | 3 (0)| 00:00:01 |
|* 24 | INDEX RANGE SCAN (MIN/MAX)| PSAJOB | 1 | 22 | 3 (0)| 00:00:01 |
|* 25 | TABLE ACCESS BY INDEX ROWID | PS_LOCATION_TBL | 1 | 25 | 2 (0)| 00:00:01 |
|* 26 | INDEX RANGE SCAN | PS_LOCATION_TBL | 1 | | 1 (0)| 00:00:01 |
| 27 | SORT AGGREGATE | | 1 | 19 | | |
| 28 | FIRST ROW | | 1 | 19 | 2 (0)| 00:00:01 |
|* 29 | INDEX RANGE SCAN (MIN/MAX) | PS_LOCATION_TBL | 1 | 19 | 2 (0)| 00:00:01 |
| 30 | TABLE ACCESS BY INDEX ROWID | PS_COUNTRY_TBL | 1 | 7 | 1 (0)| 00:00:01 |
|* 31 | INDEX UNIQUE SCAN | PS_COUNTRY_TBL | 1 | | 0 (0)| 00:00:01 |
Predicate Information (identified by operation id):
2 - filter("COUNTRY_2CHAR"=' ')
7 - access("O"."OPRID"=:B1)
9 - access("J"."EMPLID"="O"."EMPLID")
filter("J"."EFFDT"= (SELECT MAX("J1"."EFFDT") FROM "PS_JOB" "J1" WHERE "J1"."EFFDT"<=SYSDATE@! AND
"J1"."EMPL_RCD"=:B1 AND "J1"."EMPLID"=:B2) AND "J"."EFFSEQ"= (SELECT MAX("J2"."EFFSEQ") FROM "PS_JOB" "J2"
WHERE "J2"."EFFDT"=:B3 AND "J2"."EMPL_RCD"=:B4 AND "J2"."EMPLID"=:B5) AND "J"."EMPL_RCD"= (SELECT
MAX("JS"."EMPL_RCD") FROM "PS_JOB" "SYS_ALIAS_5" WHERE "JS"."EMPLID"=:B6 AND "JS"."EFFDT"= (SELECT
MAX("JS1"."EFFDT") FROM "PS_JOB" "JS1" WHERE "JS1"."EFFDT"<=SYSDATE@! AND "JS1"."EMPL_RCD"=:B7 AND
"JS1"."EMPLID"=:B8) AND "JS"."EFFSEQ"= (SELECT MAX("JS2"."EFFSEQ") FROM "PS_JOB" "JS2" WHERE "JS2"."EFFDT"=:B9
AND "JS2"."EMPL_RCD"=:B10 AND "JS2"."EMPLID"=:B11)))
12 - access("J1"."EMPLID"=:B1 AND "J1"."EMPL_RCD"=:B2 AND "J1"."EFFDT"<=SYSDATE@!)
15 - access("J2"."EMPLID"=:B1 AND "J2"."EMPL_RCD"=:B2 AND "J2"."EFFDT"=:B3)
18 - filter("JS"."EMPLID"=:B1 AND "JS"."EFFDT"= (SELECT MAX("JS1"."EFFDT") FROM "PS_JOB" "JS1" WHERE
"JS1"."EFFDT"<=SYSDATE@! AND "JS1"."EMPL_RCD"=:B2 AND "JS1"."EMPLID"=:B3) AND "JS"."EFFSEQ"= (SELECT
MAX("JS2"."EFFSEQ") FROM "PS_JOB" "JS2" WHERE "JS2"."EFFDT"=:B4 AND "JS2"."EMPL_RCD"=:B5 AND
"JS2"."EMPLID"=:B6))
21 - access("JS1"."EMPLID"=:B1 AND "JS1"."EMPL_RCD"=:B2 AND "JS1"."EFFDT"<=SYSDATE@!)
24 - access("JS2"."EMPLID"=:B1 AND "JS2"."EMPL_RCD"=:B2 AND "JS2"."EFFDT"=:B3)
25 - filter("L"."EFF_STATUS"='A')
26 - access("L"."SETID"="J"."SETID_LOCATION" AND "L"."LOCATION"="J"."LOCATION")
filter("L"."EFFDT"= (SELECT MAX("L1"."EFFDT") FROM "PS_LOCATION_TBL" "L1" WHERE "L1"."EFFDT"<=:B1 AND
"L1"."LOCATION"=:B2 AND "L1"."SETID"=:B3))
29 - access("L1"."SETID"=:B1 AND "L1"."LOCATION"=:B2 AND "L1"."EFFDT"<=:B3)
31 - access("C"."COUNTRY"="L"."COUNTRY")The line 18 looks weird, the index PSIJOB should not be used, but, according to the columns used in the query and the indexes definitions it should be PSAJOB instead.
Here the indexes definition :
PS_JOB PSAJOB EMPLID 1
PS_JOB PSAJOB EMPL_RCD 2
PS_JOB PSAJOB EFFDT 3
PS_JOB PSAJOB EFFSEQ 4
PS_JOB PSAJOB DEPTID 5
PS_JOB PSIJOB EMPL_RCD 1
PS_JOB PSIJOB REG_REGION 2
PS_JOB PSIJOB PAYGROUP 3
PS_JOB PSIJOB COMPANY 4
PS_JOB PSIJOB EMPL_STATUS 5
PS_JOB PSIJOB AB_APPR_STATUS 6
PS_JOB PSIJOB EFFDT 7
PS_JOB PSIJOB EFFSEQ 8
PS_JOB PSIJOB EMPLID 9If I drop the PSIJOB index, PSAJOB is used and query run in few minutes.
And here the explain plan if I drop this index :
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | UPDATE STATEMENT | | 1 | 52 | 45 (3)| 00:00:01 |
| 1 | UPDATE | PS_AB_PDI_CN_TAO_TMP | | | | |
|* 2 | TABLE ACCESS FULL | PS_AB_PDI_CN_TAO_TMP | 1 | 52 | 45 (3)| 00:00:01 |
| 3 | NESTED LOOPS | | 1 | 80 | 8 (0)| 00:00:01 |
| 4 | NESTED LOOPS | | 1 | 73 | 7 (0)| 00:00:01 |
| 5 | NESTED LOOPS | | 1 | 48 | 5 (0)| 00:00:01 |
| 6 | TABLE ACCESS BY INDEX ROWID | PSOPRDEFN | 1 | 15 | 2 (0)| 00:00:01 |
|* 7 | INDEX UNIQUE SCAN | PS_PSOPRDEFN | 1 | | 1 (0)| 00:00:01 |
| 8 | TABLE ACCESS BY INDEX ROWID | PS_JOB | 1 | 33 | 3 (0)| 00:00:01 |
|* 9 | INDEX RANGE SCAN | PS_JOB | 1 | | 2 (0)| 00:00:01 |
| 10 | SORT AGGREGATE | | 1 | 19 | | |
| 11 | FIRST ROW | | 14 | 266 | 3 (0)| 00:00:01 |
|* 12 | INDEX RANGE SCAN (MIN/MAX) | PSAJOB | 14 | 266 | 3 (0)| 00:00:01 |
| 13 | SORT AGGREGATE | | 1 | 22 | | |
| 14 | FIRST ROW | | 1 | 22 | 3 (0)| 00:00:01 |
|* 15 | INDEX RANGE SCAN (MIN/MAX) | PSAJOB | 1 | 22 | 3 (0)| 00:00:01 |
| 16 | SORT AGGREGATE | | 1 | 22 | | |
| 17 | FIRST ROW | | 1 | 22 | 7 (58)| 00:00:01 |
|* 18 | INDEX RANGE SCAN (MIN/MAX) | PSAJOB | 1 | 22 | 7 (58)| 00:00:01 |
| 19 | SORT AGGREGATE | | 1 | 19 | | |
| 20 | FIRST ROW | | 14 | 266 | 3 (0)| 00:00:01 |
|* 21 | INDEX RANGE SCAN (MIN/MAX) | PSAJOB | 14 | 266 | 3 (0)| 00:00:01 |
| 22 | SORT AGGREGATE | | 1 | 22 | | |
| 23 | FIRST ROW | | 1 | 22 | 3 (0)| 00:00:01 |
|* 24 | INDEX RANGE SCAN (MIN/MAX)| PSAJOB | 1 | 22 | 3 (0)| 00:00:01 |
|* 25 | TABLE ACCESS BY INDEX ROWID | PS_LOCATION_TBL | 1 | 25 | 2 (0)| 00:00:01 |
|* 26 | INDEX RANGE SCAN | PS_LOCATION_TBL | 1 | | 1 (0)| 00:00:01 |
| 27 | SORT AGGREGATE | | 1 | 19 | | |
| 28 | FIRST ROW | | 1 | 19 | 2 (0)| 00:00:01 |
|* 29 | INDEX RANGE SCAN (MIN/MAX) | PS_LOCATION_TBL | 1 | 19 | 2 (0)| 00:00:01 |
| 30 | TABLE ACCESS BY INDEX ROWID | PS_COUNTRY_TBL | 1 | 7 | 1 (0)| 00:00:01 |
|* 31 | INDEX UNIQUE SCAN | PS_COUNTRY_TBL | 1 | | 0 (0)| 00:00:01 |
Predicate Information (identified by operation id):
2 - filter("COUNTRY_2CHAR"=' ')
7 - access("O"."OPRID"=:B1)
9 - access("J"."EMPLID"="O"."EMPLID")
filter("J"."EFFDT"= (SELECT MAX("J1"."EFFDT") FROM "PS_JOB" "J1" WHERE "J1"."EFFDT"<=SYSDATE@! AND
"J1"."EMPL_RCD"=:B1 AND "J1"."EMPLID"=:B2) AND "J"."EFFSEQ"= (SELECT MAX("J2"."EFFSEQ") FROM "PS_JOB" "J2"
WHERE "J2"."EFFDT"=:B3 AND "J2"."EMPL_RCD"=:B4 AND "J2"."EMPLID"=:B5) AND "J"."EMPL_RCD"= (SELECT
MAX("JS"."EMPL_RCD") FROM "PS_JOB" "SYS_ALIAS_5" WHERE "JS"."EMPLID"=:B6 AND "JS"."EFFDT"= (SELECT
MAX("JS1"."EFFDT") FROM "PS_JOB" "JS1" WHERE "JS1"."EFFDT"<=SYSDATE@! AND "JS1"."EMPL_RCD"=:B7 AND
"JS1"."EMPLID"=:B8) AND "JS"."EFFSEQ"= (SELECT MAX("JS2"."EFFSEQ") FROM "PS_JOB" "JS2" WHERE "JS2"."EFFDT"=:B9
AND "JS2"."EMPL_RCD"=:B10 AND "JS2"."EMPLID"=:B11)))
12 - access("J1"."EMPLID"=:B1 AND "J1"."EMPL_RCD"=:B2 AND "J1"."EFFDT"<=SYSDATE@!)
15 - access("J2"."EMPLID"=:B1 AND "J2"."EMPL_RCD"=:B2 AND "J2"."EFFDT"=:B3)
18 - access("JS"."EMPLID"=:B1)
filter("JS"."EFFDT"= (SELECT MAX("JS1"."EFFDT") FROM "PS_JOB" "JS1" WHERE "JS1"."EFFDT"<=SYSDATE@! AND
"JS1"."EMPL_RCD"=:B1 AND "JS1"."EMPLID"=:B2) AND "JS"."EFFSEQ"= (SELECT MAX("JS2"."EFFSEQ") FROM "PS_JOB"
"JS2" WHERE "JS2"."EFFDT"=:B3 AND "JS2"."EMPL_RCD"=:B4 AND "JS2"."EMPLID"=:B5))
21 - access("JS1"."EMPLID"=:B1 AND "JS1"."EMPL_RCD"=:B2 AND "JS1"."EFFDT"<=SYSDATE@!)
24 - access("JS2"."EMPLID"=:B1 AND "JS2"."EMPL_RCD"=:B2 AND "JS2"."EFFDT"=:B3)
25 - filter("L"."EFF_STATUS"='A')
26 - access("L"."SETID"="J"."SETID_LOCATION" AND "L"."LOCATION"="J"."LOCATION")
filter("L"."EFFDT"= (SELECT MAX("L1"."EFFDT") FROM "PS_LOCATION_TBL" "L1" WHERE "L1"."EFFDT"<=:B1 AND
"L1"."LOCATION"=:B2 AND "L1"."SETID"=:B3))
29 - access("L1"."SETID"=:B1 AND "L1"."LOCATION"=:B2 AND "L1"."EFFDT"<=:B3)
31 - access("C"."COUNTRY"="L"."COUNTRY")As you can see, the cost is exactly same for the line 18, however it is using a different index and scan.
Do you have any explanation why Oracle is using PSIJOB instead of PSAJOB in first case ?
How Oracle could prefer a INDEX FULL SCAN than INDEX RANGE SCAN (PS_JOB is a 3.3 millions rows table) ?
Lastly, here an extract of the trace 10053 file when PSIJOB is used :
QUERY BLOCK TEXT
SELECT MAX(js.EMPL_RCD)
FROM PS_JOB js
WHERE js.EMPLID = j.EMPLID
AND js.EFFDT = (SELECT MAX(js1.EFFDT)
FROM PS_JOB js1
WHERE js1.EMPLID = js.EMPLID
AND js1.EMPL_RCD = js.EMPL_RCD
AND js1.EFFDT <= sysdate)
AND js.EFFSEQ = (SELECT MAX(js2.EFFSEQ)
FROM PS_JOB js2
WHERE js2.EMPLID = js.EMPLID
AND js2.EMPL_RCD = js.EMPL_RCD
AND js2.EFFDT = js.EFFDT)
Index Stats::
Index: PSAJOB Col#: 1 2 3 4 5
LVLS: 2 #LB: 16434 #DK: 3155830 LB/K: 1.00 DB/K: 1.00 CLUF: 3020072.00
Index: PSIJOB Col#: 2 72 23 22 10 229 3 4 1
LVLS: 2 #LB: 21287 #DK: 3303072 LB/K: 1.00 DB/K: 1.00 CLUF: 3035026.00
SINGLE TABLE ACCESS PATH
BEGIN Single Table Cardinality Estimation
Column (#1): EMPLID(VARCHAR2)
AvgLen: 8.00 NDV: 116590 Nulls: 0 Density: 8.5771e-06
Histogram: HtBal #Bkts: 254 UncompBkts: 254 EndPtVals: 255
Column (#3): EFFDT(DATE)
AvgLen: 8.00 NDV: 2085 Nulls: 0 Density: 2.6799e-04 Min: 2415386 Max: 2455585
Histogram: HtBal #Bkts: 254 UncompBkts: 254 EndPtVals: 183
Column (#2): EMPL_RCD(NUMBER)
AvgLen: 3.00 NDV: 2 Nulls: 0 Density: 0.0026359 Min: 0 Max: 1
Histogram: Freq #Bkts: 2 UncompBkts: 5501 EndPtVals: 2
Column (#4): EFFSEQ(NUMBER)
AvgLen: 3.00 NDV: 5 Nulls: 0 Density: 9.0893e-05 Min: 0 Max: 4
Histogram: Freq #Bkts: 5 UncompBkts: 5501 EndPtVals: 5
Table: PS_JOB Alias: SYS_ALIAS_5
Card: Original: 3282026 Rounded: 28 Computed: 28.15 Non Adjusted: 28.15
END Single Table Cardinality Estimation
Access Path: index (index (FFS))
Index: PSAJOB
resc_io: 2848.00 resc_cpu: 653526199
ix_sel: 0.0000e+00 ix_sel_with_filters: 1
Access Path: index (FFS)
Cost: 3306.55 Resp: 3306.55 Degree: 1
Cost_io: 2848.00 Cost_cpu: 653526199
Resp_io: 2848.00 Resp_cpu: 653526199
Access Path: index (index (FFS))
Index: PSIJOB
resc_io: 3688.00 resc_cpu: 713117750
ix_sel: 0.0000e+00 ix_sel_with_filters: 1
Access Path: index (FFS)
Cost: 4188.36 Resp: 4188.36 Degree: 1
Cost_io: 3688.00 Cost_cpu: 713117750
Resp_io: 3688.00 Resp_cpu: 713117750
Access Path: index (Min/Max)
Index: PSAJOB
resc_io: 3.00 resc_cpu: 21564
ix_sel: 0.035714 ix_sel_with_filters: 0.035714
Cost: 7.13 Resp: 7.13 Degree: 1
Access Path: index (Min/Max)
Index: PSIJOB
resc_io: 3.00 resc_cpu: 21564
ix_sel: 0.035714 ix_sel_with_filters: 0.035714
Cost: 7.13 Resp: 7.13 Degree: 1
Best:: AccessPath: IndexRange Index: PSIJOB
Cost: 7.13 Degree: 1 Resp: 7.13 Card: 28.15 Bytes: 0
Card adjusted, Rounded Card: 1 Computed Card: 0.00
...Thanks.I don't know if you are interested, but I did the following test, and I get a new explain plan :
SQL> alter session set optimizer_features_enable='9.2.0';
Session altered.
SQL>
SQL> DECLARE
2 my_task_name VARCHAR2(30);
3 my_sqltext CLOB;
4 BEGIN
5 my_sqltext := 'UPDATE ps_AB_PDI_CN_TAO_TMP
6 SET country_2char = COALESCE((
7 SELECT c.COUNTRY_2CHAR
8 FROM PSOPRDEFN o
9 , PS_JOB j
10 , PS_LOCATION_TBL l
11 , PS_COUNTRY_TBL c
12 WHERE j.EMPLID = o.EMPLID
13 AND j.EFFDT = (SELECT MAX(j1.EFFDT)
14 FROM PS_JOB j1
15 WHERE j1.EMPLID = j.EMPLID
16 AND j1.EMPL_RCD = j.EMPL_RCD
17 AND j1.EFFDT <= sysdate)
18 AND j.EFFSEQ = (SELECT MAX(j2.EFFSEQ)
19 FROM PS_JOB j2
20 WHERE j2.EMPLID = j.EMPLID
21 AND j2.EMPL_RCD = j.EMPL_RCD
22 AND j2.EFFDT = j.EFFDT)
23 AND j.EMPL_RCD = (SELECT MAX(js.EMPL_RCD)
24 FROM PS_JOB js
25 WHERE js.EMPLID = j.EMPLID
26 AND js.EFFDT = (SELECT MAX(js1.EFFDT)
27 FROM PS_JOB js1
28 WHERE js1.EMPLID = js.EMPLID
29 AND js1.EMPL_RCD = js.EMPL_RCD
30 AND js1.EFFDT <= sysdate)
31 AND js.EFFSEQ = (SELECT MAX(js2.EFFSEQ)
32 FROM PS_JOB js2
33 WHERE js2.EMPLID = js.EMPLID
34 AND js2.EMPL_RCD = js.EMPL_RCD
35 AND js2.EFFDT = js.EFFDT))
36 AND l.SETID = j.SETID_LOCATION
37 AND l.LOCATION = j.LOCATION
38 AND l.EFFDT = (SELECT MAX(l1.EFFDT)
39 FROM PS_LOCATION_TBL l1
40 WHERE l1.SETID = l.SETID
41 AND l1.LOCATION = l.LOCATION
42 AND l1.EFFDT <= j.EFFDT)
43 AND l.EFF_STATUS = ''A''
44 AND c.COUNTRY = l.COUNTRY
45 AND o.oprid = ps_AB_PDI_CN_TAO_TMP.OPRID),'' '' )
46 WHERE COUNTRY_2CHAR = '' ''';
47 my_task_name := DBMS_SQLTUNE.CREATE_TUNING_TASK(
48 sql_text => my_sqltext,
49 user_name => 'SYSADM',
50 scope => 'COMPREHENSIVE',
51 time_limit => 3600,
52 task_name => 'sysadm_avoid_psijob',
53 description => 'Task to avoid PSIJOB index on update - PDI');
54 END;
55 /
PL/SQL procedure successfully completed.
SQL>
SQL> BEGIN
2 DBMS_SQLTUNE.EXECUTE_TUNING_TASK( task_name => 'sysadm_avoid_psijob');
3 end;
4 /
PL/SQL procedure successfully completed.
SQL>
SQL> SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK( 'sysadm_avoid_psijob') from DUAL;
GENERAL INFORMATION SECTION
Tuning Task Name : sysadm_avoid_psijob
Tuning Task Owner : SYSADM
Scope : COMPREHENSIVE
Time Limit(seconds) : 3600
Completion Status : COMPLETED
Started at : 07/03/2009 20:35:36
Completed at : 07/03/2009 20:38:40
Number of Statistic Findings : 1
Number of SQL Profile Findings : 1
Schema Name: SYSADM
SQL ID : 7xcbcszgj1znc
SQL Text : UPDATE ps_AB_PDI_CN_TAO_TMP
SET country_2char = COALESCE((
SELECT c.COUNTRY_2CHAR
FROM PSOPRDEFN o
, PS_JOB j
, PS_LOCATION_TBL l
, PS_COUNTRY_TBL c
WHERE j.EMPLID = o.EMPLID
AND j.EFFDT = (SELECT MAX(j1.EFFDT)
FROM PS_JOB j1
WHERE j1.EMPLID = j.EMPLID
AND j1.EMPL_RCD = j.EMPL_RCD
AND j1.EFFDT <= sysdate)
AND j.EFFSEQ = (SELECT MAX(j2.EFFSEQ)
FROM PS_JOB j2
WHERE j2.EMPLID = j.EMPLID
AND j2.EMPL_RCD = j.EMPL_RCD
AND j2.EFFDT = j.EFFDT)
AND j.EMPL_RCD = (SELECT MAX(js.EMPL_RCD)
FROM PS_JOB js
WHERE js.EMPLID = j.EMPLID
AND js.EFFDT = (SELECT MAX(js1.EFFDT)
FROM PS_JOB js1
WHERE js1.EMPLID = js.EMPLID
AND js1.EMPL_RCD = js.EMPL_RCD
AND js1.EFFDT <= sysdate)
AND js.EFFSEQ = (SELECT MAX(js2.EFFSEQ)
FROM PS_JOB js2
WHERE js2.EMPLID = js.EMPLID
AND js2.EMPL_RCD =
js.EMPL_RCD
AND js2.EFFDT = js.EFFDT))
AND l.SETID = j.SETID_LOCATION
AND l.LOCATION = j.LOCATION
AND l.EFFDT = (SELECT MAX(l1.EFFDT)
FROM PS_LOCATION_TBL l1
WHERE l1.SETID = l.SETID
AND l1.LOCATION = l.LOCATION
AND l1.EFFDT <= j.EFFDT)
AND l.EFF_STATUS = 'A'
AND c.COUNTRY = l.COUNTRY
AND o.oprid = ps_AB_PDI_CN_TAO_TMP.OPRID),' ' )
WHERE COUNTRY_2CHAR = ' '
FINDINGS SECTION (2 findings)
1- Statistics Finding
Optimizer statistics for table "SYSADM"."PS_AB_PDI_CN_TAO_TMP" and its
indices are stale.
Recommendation
- Consider collecting optimizer statistics for this table.
execute dbms_stats.gather_table_stats(ownname => 'SYSADM', tabname =>
'PS_AB_PDI_CN_TAO_TMP', estimate_percent =>
DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt => 'FOR ALL COLUMNS SIZE
AUTO');
Rationale
The optimizer requires up-to-date statistics for the table in order to
select a good execution plan.
2- SQL Profile Finding (see explain plans section below)
A potentially better execution plan was found for this statement.
Recommendation (estimated benefit<=10%)
- Consider accepting the recommended SQL profile.
execute dbms_sqltune.accept_sql_profile(task_name =>
'sysadm_avoid_psijob', replace => TRUE);
EXPLAIN PLANS SECTION
1- Original With Adjusted Cost
Plan hash value: 4225281431
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | UPDATE STATEMENT | | 48482 | 284K| 54 (19)| 00:00:01 |
| 1 | UPDATE | PS_AB_PDI_CN_TAO_TMP | | | | |
|* 2 | TABLE ACCESS FULL | PS_AB_PDI_CN_TAO_TMP | 48482 | 284K| 54 (19)| 00:00:01 |
| 3 | NESTED LOOPS | | 1 | 80 | 8 (0)| 00:00:01 |
| 4 | NESTED LOOPS | | 1 | 73 | 7 (0)| 00:00:01 |
| 5 | NESTED LOOPS | | 1 | 48 | 5 (0)| 00:00:01 |
| 6 | TABLE ACCESS BY INDEX ROWID | PSOPRDEFN | 1 | 15 | 2 (0)| 00:00:01 |
|* 7 | INDEX UNIQUE SCAN | PS_PSOPRDEFN | 1 | | 1 (0)| 00:00:01 |
| 8 | TABLE ACCESS BY INDEX ROWID | PS_JOB | 1 | 33 | 3 (0)| 00:00:01 |
|* 9 | INDEX RANGE SCAN | PSAJOB | 1 | | 2 (0)| 00:00:01 |
| 10 | SORT AGGREGATE | | 1 | 19 | | |
| 11 | FIRST ROW | | 10 | 190 | 3 (0)| 00:00:01 |
|* 12 | INDEX RANGE SCAN (MIN/MAX) | PSAJOB | 10 | 190 | 3 (0)| 00:00:01 |
| 13 | SORT AGGREGATE | | 1 | 22 | | |
| 14 | FIRST ROW | | 1 | 22 | 3 (0)| 00:00:01 |
|* 15 | INDEX RANGE SCAN (MIN/MAX) | PSAJOB | 1 | 22 | 3 (0)| 00:00:01 |
| 16 | SORT AGGREGATE | | 1 | 22 | | |
| 17 | FIRST ROW | | 1 | 22 | 9 (67)| 00:00:01 |
|* 18 | INDEX RANGE SCAN (MIN/MAX) | PSAJOB | 1 | 22 | 9 (67)| 00:00:01 |
| 19 | SORT AGGREGATE | | 1 | 19 | | |
| 20 | FIRST ROW | | 10 | 190 | 3 (0)| 00:00:01 |
|* 21 | INDEX RANGE SCAN (MIN/MAX) | PSAJOB | 10 | 190 | 3 (0)| 00:00:01 |
| 22 | SORT AGGREGATE | | 1 | 22 | | |
| 23 | FIRST ROW | | 1 | 22 | 3 (0)| 00:00:01 |
|* 24 | INDEX RANGE SCAN (MIN/MAX)| PSAJOB | 1 | 22 | 3 (0)| 00:00:01 |
|* 25 | TABLE ACCESS BY INDEX ROWID | PS_LOCATION_TBL | 1 | 25 | 2 (0)| 00:00:01 |
|* 26 | INDEX RANGE SCAN | PS_LOCATION_TBL | 1 | | 1 (0)| 00:00:01 |
| 27 | SORT AGGREGATE | | 1 | 19 | | |
| 28 | FIRST ROW | | 1 | 19 | 2 (0)| 00:00:01 |
|* 29 | INDEX RANGE SCAN (MIN/MAX) | PS_LOCATION_TBL | 1 | 19 | 2 (0)| 00:00:01 |
| 30 | TABLE ACCESS BY INDEX ROWID | PS_COUNTRY_TBL | 1 | 7 | 1 (0)| 00:00:01 |
|* 31 | INDEX UNIQUE SCAN | PS_COUNTRY_TBL | 1 | | 0 (0)| 00:00:01 |
Predicate Information (identified by operation id):
2 - filter("COUNTRY_2CHAR"=' ')
7 - access("O"."OPRID"=:B1)
9 - access("J"."EMPLID"="O"."EMPLID")
filter("J"."EFFDT"= (SELECT /*+ INDEX ("J1" "PSAJOB") */ MAX("J1"."EFFDT") FROM "PS_JOB" "J1" WHERE
"J1"."EFFDT"<=SYSDATE@! AND "J1"."EMPL_RCD"=:B1 AND "J1"."EMPLID"=:B2) AND "J"."EFFSEQ"= (SELECT /*+ INDEX
("J2" "PSAJOB") */ MAX("J2"."EFFSEQ") FROM "PS_JOB" "J2" WHERE "J2"."EFFDT"=:B3 AND "J2"."EMPL_RCD"=:B4 AND
"J2"."EMPLID"=:B5) AND "J"."EMPL_RCD"= (SELECT /*+ INDEX ("SYS_ALIAS_5" "PSAJOB") */ MAX("JS"."EMPL_RCD") FR
"PS_JOB" "SYS_ALIAS_5" WHERE "JS"."EMPLID"=:B6 AND "JS"."EFFDT"= (SELECT /*+ INDEX ("JS1" "PSAJOB") */
MAX("JS1"."EFFDT") FROM "PS_JOB" "JS1" WHERE "JS1"."EFFDT"<=SYSDATE@! AND "JS1"."EMPL_RCD"=:B7 AND
"JS1"."EMPLID"=:B8) AND "JS"."EFFSEQ"= (SELECT /*+ INDEX ("JS2" "PSAJOB") */ MAX("JS2"."EFFSEQ") FROM "PS_JO
"JS2" WHERE "JS2"."EFFDT"=:B9 AND "JS2"."EMPL_RCD"=:B10 AND "JS2"."EMPLID"=:B11)))
12 - access("J1"."EMPLID"=:B1 AND "J1"."EMPL_RCD"=:B2 AND "J1"."EFFDT"<=SYSDATE@!)
15 - access("J2"."EMPLID"=:B1 AND "J2"."EMPL_RCD"=:B2 AND "J2"."EFFDT"=:B3)
18 - access("JS"."EMPLID"=:B1)
filter("JS"."EFFDT"= (SELECT /*+ INDEX ("JS1" "PSAJOB") */ MAX("JS1"."EFFDT") FROM "PS_JOB" "JS1" WHERE
"JS1"."EFFDT"<=SYSDATE@! AND "JS1"."EMPL_RCD"=:B1 AND "JS1"."EMPLID"=:B2) AND "JS"."EFFSEQ"= (SELECT /*+ IND
("JS2" "PSAJOB") */ MAX("JS2"."EFFSEQ") FROM "PS_JOB" "JS2" WHERE "JS2"."EFFDT"=:B3 AND "JS2"."EMPL_RCD"=:B4
AND "JS2"."EMPLID"=:B5))
21 - access("JS1"."EMPLID"=:B1 AND "JS1"."EMPL_RCD"=:B2 AND "JS1"."EFFDT"<=SYSDATE@!)
24 - access("JS2"."EMPLID"=:B1 AND "JS2"."EMPL_RCD"=:B2 AND "JS2"."EFFDT"=:B3)
25 - filter("L"."EFF_STATUS"='A')
26 - access("L"."SETID"="J"."SETID_LOCATION" AND "L"."LOCATION"="J"."LOCATION")
filter("L"."EFFDT"= (SELECT /*+ INDEX ("L1" "PS_LOCATION_TBL") */ MAX("L1"."EFFDT") FROM
"PS_LOCATION_TBL" "L1" WHERE "L1"."EFFDT"<=:B1 AND "L1"."LOCATION"=:B2 AND "L1"."SETID"=:B3))
29 - access("L1"."SETID"=:B1 AND "L1"."LOCATION"=:B2 AND "L1"."EFFDT"<=:B3)
31 - access("C"."COUNTRY"="L"."COUNTRY")
2- Using SQL Profile
Plan hash value: 1175485146
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
| 0 | UPDATE STATEMENT | | 48482 | 284K| | 54 (19)| 00:00:01 |
| 1 | UPDATE | PS_AB_PDI_CN_TAO_TMP | | | | | |
|* 2 | TABLE ACCESS FULL | PS_AB_PDI_CN_TAO_TMP | 48482 | 284K| | 54 (19)| 00:00:01 |
| 3 | NESTED LOOPS | | 1 | 133 | | 17470 (4)| 00:03:30 |
| 4 | NESTED LOOPS | | 1 | 80 | | 8 (0)| 00:00:01 |
| 5 | NESTED LOOPS | | 1 | 73 | | 7 (0)| 00:00:01 |
| 6 | NESTED LOOPS | | 1 | 48 | | 5 (0)| 00:00:01 |
| 7 | TABLE ACCESS BY INDEX ROWID | PSOPRDEFN | 1 | 15 | | 2 (0)| 00:00:01 |
|* 8 | INDEX UNIQUE SCAN | PS_PSOPRDEFN | 1 | | | 1 (0)| 00:00:01 |
| 9 | TABLE ACCESS BY INDEX ROWID | PS_JOB | 1 | 33 | | 3 (0)| 00:00:01 |
|* 10 | INDEX RANGE SCAN | PSAJOB | 1 | | | 2 (0)| 00:00:01 |
| 11 | SORT AGGREGATE | | 1 | 19 | | | |
| 12 | FIRST ROW | | 10 | 190 | | 3 (0)| 00:00:01 |
|* 13 | INDEX RANGE SCAN (MIN/MAX)| PSAJOB | 10 | 190 | | 3 (0)| 00:00:01 |
| 14 | SORT AGGREGATE | | 1 | 115 | | | |
|* 15 | HASH JOIN | | 1 | 115 | | 10 (30)| 00:00:01 |
| 16 | NESTED LOOPS | | 1 | 75 | | 5 (20)| 00:00:01 |
| 17 | VIEW | VW_SQ_2 | 19 | 1007 | | 4 (25)| 00:00:01 |
| 18 | SORT GROUP BY | | 19 | 779 | | 4 (25)| 00:00:01 |
|* 19 | INDEX RANGE SCAN | PSAJOB | 19 | 779 | | 3 (0)| 00:00:01 |
|* 20 | INDEX UNIQUE SCAN | PS_JOB | 1 | 22 | | 1 (0)| 00:00:01 |
| 21 | VIEW | VW_SQ_1 | 19 | 760 | | 4 (25)| 00:00:01 |
| 22 | SORT GROUP BY | | 19 | 570 | | 4 (25)| 00:00:01 |
|* 23 | INDEX RANGE SCAN | PSAJOB | 19 | 570 | | 3 (0)| 00:00:01 |
|* 24 | TABLE ACCESS BY INDEX ROWID | PS_LOCATION_TBL | 1 | 25 | | 2 (0)| 00:00:01 |
|* 25 | INDEX RANGE SCAN | PS_LOCATION_TBL | 1 | | | 1 (0)| 00:00:01 |
| 26 | SORT AGGREGATE | | 1 | 19 | | | |
| 27 | FIRST ROW | | 1 | 19 | | 2 (0)| 00:00:01 |
|* 28 | INDEX RANGE SCAN (MIN/MAX) | PS_LOCATION_TBL | 1 | 19 | | 2 (0)| 00:00:01 |
| 29 | TABLE ACCESS BY INDEX ROWID | PS_COUNTRY_TBL | 1 | 7 | | 1 (0)| 00:00:01 |
|* 30 | INDEX UNIQUE SCAN | PS_COUNTRY_TBL | 1 | | | 0 (0)| 00:00:01 |
|* 31 | VIEW | VW_SQ_3 | 1 | 53 | | 17462 (4)| 00:03:30 |
| 32 | SORT GROUP BY | | 3299K| 129M| 379M| 17462 (4)| 00:03:30 |
| 33 | INDEX FULL SCAN | PSAJOB | 3299K| 129M| | 17462 (4)| 00:03:30 |
Predicate Information (identified by operation id):
2 - filter("COUNTRY_2CHAR"=' ')
8 - access("O"."OPRID"=:B1)
10 - access("J"."EMPLID"="O"."EMPLID")
filter("J"."EFFDT"= (SELECT MAX("J1"."EFFDT") FROM "PS_JOB" "J1" WHERE "J1"."EFFDT"<=SYSDATE@! AND
"J1"."EMPL_RCD"=:B1 AND "J1"."EMPLID"=:B2) AND "J"."EMPL_RCD"= (SELECT MAX("JS"."EMPL_RCD") FROM "PS_JOB"
"JS", (SELECT MAX("JS1"."EFFDT") "VW_COL_1","JS1"."EMPLID" "EMPLID","JS1"."EMPL_RCD" "EMPL_RCD" FROM
"PS_JOB" "JS1" WHERE "JS1"."EMPLID"=:B3 AND "JS1"."EFFDT"<=SYSDATE@! GROUP BY
"JS1"."EMPLID","JS1"."EMPL_RCD") "VW_SQ_1", (SELECT MAX("JS2"."EFFSEQ") "VW_COL_1","JS2"."EMPLID"
"EMPLID","JS2"."EMPL_RCD" "EMPL_RCD","JS2"."EFFDT" "EFFDT" FROM "PS_JOB" "JS2" WHERE "JS2"."EMPLID"=:B4
GROUP BY "JS2"."EMPLID","JS2"."EMPL_RCD","JS2"."EFFDT") "VW_SQ_2" WHERE "EMPL_RCD"="JS"."EMPL_RCD" AND
"EMPLID"="JS"."EMPLID" AND "JS"."EFFDT"="VW_COL_1" AND "JS"."EFFSEQ"="VW_COL_1" AND "EFFDT"="JS"."EFFDT"
AND "EMPL_RCD"="JS"."EMPL_RCD" AND "EMPLID"="JS"."EMPLID" AND "JS"."EMPLID"=:B5))
13 - access("J1"."EMPLID"=:B1 AND "J1"."EMPL_RCD"=:B2 AND "J1"."EFFDT"<=SYSDATE@!)
15 - access("JS"."EFFDT"="VW_COL_1" AND "EMPLID"="JS"."EMPLID" AND "EMPL_RCD"="JS"."EMPL_RCD")
19 - access("JS2"."EMPLID"=:B1)
20 - access("EMPLID"="JS"."EMPLID" AND "EMPL_RCD"="JS"."EMPL_RCD" AND "EFFDT"="JS"."EFFDT" AND
"JS"."EFFSEQ"="VW_COL_1")
filter("JS"."EMPLID"=:B1)
23 - access("JS1"."EMPLID"=:B1 AND "JS1"."EFFDT"<=SYSDATE@!)
filter("JS1"."EFFDT"<=SYSDATE@!)
24 - filter("L"."EFF_STATUS"='A')
25 - access("L"."SETID"="J"."SETID_LOCATION" AND "L"."LOCATION"="J"."LOCATION")
filter("L"."EFFDT"= (SELECT MAX("L1"."EFFDT") FROM "PS_LOCATION_TBL" "L1" WHERE "L1"."EFFDT"<=:B1
AND "L1"."LOCATION"=:B2 AND "L1"."SETID"=:B3))
28 - access("L1"."SETID"=:B1 AND "L1"."LOCATION"=:B2 AND "L1"."EFFDT"<=:B3)
30 - access("C"."COUNTRY"="L"."COUNTRY")
31 - filter("J"."EFFSEQ"="VW_COL_1" AND "EMPLID"="J"."EMPLID" AND "EMPL_RCD"="J"."EMPL_RCD" AND
"EFFDT"="J"."EFFDT")
-------------------------------------------------------------------------------{code}
If I accept this new explain plan, the query is not improved, it run longer than expected, especially longer than the previous one (using only PSAJOB). -
Index not getting used in spite of hints
Its Oracle 10g Release 10.2.0.4.0 Hi All,
I have this query in which there is are indexes on Intrument table like this:
Instrument:
idx 1 : (INSTRUMENT_ID, END_COB_DATE, CLOSE_ACTION_ID, PRODUCT_SUB_TYPE_ID, BEGIN_COB_DATE)
idx 2 : ( INSTRUMENT_ID, INSTRUMENT_VN, END_COB_DATE, CLOSE_ACTION_ID)
idx 3 : (CLOSE_ACTION_ID, END_COB_DATE)I tried all the possible ways but none of the indexes are getting used causing full table scans of this table. I need some guidance on how can I avoid this FTS so the query can run fast and use the index on Instrument table:
query:
select distinct i.instrument_id,
i.name,
case
when (mn2.display_name != 'DEBT PRIORITY CLASS' and
mn2.display_name is not null) then
mn2.display_name
else
mn1.display_name
end "DEBT_PRIORITY_CLASS"
from instrument i, inst_debt id
left join marsnode mn1 on (id.debt_priority_class_id = mn1.node_id and
mn1.close_date is null and
mn1.type_id = 58412926883279)
left join marsnodelink mnl1 on (mn1.node_id = mnl1.node_id and
mnl1.close_date is null and
mnl1.begin_cob_date <=
TO_DATE('27-Oct-2010', 'DD-Mon-YYYY') and
mnl1.end_cob_date >
TO_DATE('27-Oct-2010', 'DD-Mon-YYYY'))
left join marsnode mn2 on (mnl1.parent_id = mn2.node_id and
mn2.close_date is null and
mn2.type_id = 58412926883279)
where i.instrument_id = id.instrument_id
and i.instrument_vn = id.instrument_vn
AND i.end_cob_date > TO_DATE('27-Oct-2010', 'DD-Mon-YYYY')
AND i.close_action_id is null
AND i.product_sub_type_id = 3
AND i.begin_cob_date <= TO_DATE('27-Oct-2010', 'DD-Mon-YYYY')This is the execution plan
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)|
| 0 | SELECT STATEMENT | | 2026K| 407M| | 509K (20)|
| 1 | HASH UNIQUE | | 2026K| 407M| 879M| 509K (20)|
|* 2 | HASH JOIN RIGHT OUTER | | 2026K| 407M| | 426K (23)|
|* 3 | TABLE ACCESS BY INDEX ROWID | MARSNODE | 501 | 23046 | | 239 (3)|
|* 4 | INDEX RANGE SCAN | FKI_38576_TYPE_ID | 10159 | | | 34 (6)|
|* 5 | HASH JOIN RIGHT OUTER | | 2026K| 318M| | 425K (23)|
|* 6 | TABLE ACCESS FULL | MARSNODELINK | 330 | 15510 | | 6560 (16)|
|* 7 | HASH JOIN RIGHT OUTER | | 2026K| 228M| | 419K (23)|
|* 8 | TABLE ACCESS BY INDEX ROWID| MARSNODE | 501 | 23046 | | 239 (3)|
|* 9 | INDEX RANGE SCAN | FKI_38576_TYPE_ID | 10159 | | | 34 (6)|
|* 10 | HASH JOIN | | 2026K| 139M| 34M| 418K (23)|
| 11 | TABLE ACCESS FULL | INST_DEBT | 1031K| 22M| | 1665 (30)|
*|* 12 | TABLE ACCESS FULL | INSTRUMENT | 2062K| 96M| | 413K (23)|*
--------------------------------------------------------------------------------------------------predicate info
2 - access("MNL1"."PARENT_ID"="MN2"."NODE_ID"(+))
3 - filter("MN2"."CLOSE_DATE"(+) IS NULL)
4 - access("MN2"."TYPE_ID"(+)=58412926883279)
5 - access("MN1"."NODE_ID"="MNL1"."NODE_ID"(+))
6 - filter("MNL1"."CLOSE_DATE"(+) IS NULL AND "MNL1"."END_COB_DATE"(+)>TO_DATE('
2010-10-27 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "MNL1"."BEGIN_COB_DATE"(+)<=TO_DATE('
2010-10-27 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
7 - access("ID"."DEBT_PRIORITY_CLASS_ID"="MN1"."NODE_ID"(+))
8 - filter("MN1"."CLOSE_DATE"(+) IS NULL)
9 - access("MN1"."TYPE_ID"(+)=58412926883279)
10 - access("I"."INSTRUMENT_ID"="ID"."INSTRUMENT_ID" AND
"I"."INSTRUMENT_VN"="ID"."INSTRUMENT_VN")
12 - filter("I"."PRODUCT_SUB_TYPE_ID"=3 AND "I"."CLOSE_ACTION_ID" IS NULL AND
"I"."END_COB_DATE">TO_DATE(' 2010-10-27 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND
"I"."BEGIN_COB_DATE"<=TO_DATE(' 2010-10-27 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))Regards,
AashishAashish S. wrote:
I tried all the possible ways but none of the indexes are getting used causing full table scans of this table. I need some guidance on how can I avoid this FTS so the query can run fast and use the index on Instrument table:I assume the last part of the above statement is what you actually need to achieve (i.e. improve execution time of the query) and the query not using index is what you think the "cause" for the actual "problem". I will try to answer the actual "problem". Based on what you have posted, some observations/suggestions
1) Your plan shows the query is expected to retrieve 2026K rows. Are you sure you need to retrieve that many records? You may want to revisit the "requirement" here.
2) Continuing above point, you may want to post details of how much time the query is taking to execute at present and how much time do you expect it to take. Another most important details will be how are you measuring the query execution time. With that huge number of records, it is quite possible that more time is being spent in just transferring the query results to the "client" than actual time taken by server to execute the query.
3) If what you have posted is the order of columns in the indexes on INSTRUMENT table, then which index do you think will help the query execution and how? The order of columns suggest that none of the indexes will be good enough and that seems to be the right choice.
4) Your predicate section states that filter predicate on INSTRUMENT table generates 2062K rows. How many records exist in INSTRUMENT table? You will need to have many times more records (besides other factors like ordering of table data etc.) in the table to justify the indexed access to fetch these huge number of rows.
5) Finally, you may want to verify whether the statistics on tables and indexes used by the query are up-to-date.
Hope this helps. -
What is RID in non clustered index and its use
Hi All,
I need help regarding following articles on sql server
1) what is RID in non clustered index and its use.
2) What is Physical and virtual address space. Difference in 32 bit vs 64 bit Virtual address space
Regards
RahulNext time Please ask single question in a thread you will get better response.
1. RID is location of heap. When you create Non clustered index on heap and
lookup happens to get extra records RID is used to locate the records. RID is basically Row ID. This is basic definition for you. Please read
this Thread for more details
2. I have not heard of Physical address space. I Know Virtual address space( VAS)
VAS is simple terms is amount of memory( virtual ) 'visible' to a process, a process can be SQL Server process or windows process. It theoretically depends on architecture of Operating System. 32 bit OS will have maximum range of 4 G VAS, it's calculated
like a process ruining on 32 bit system can address max up to 2^32 locations ( which is equivalent to 4 G). Similarly for 64 bit max VAS will be 2^64 which is theoretically infinite. To make things feasible maximum VAS for 64 bit system is kept to 8 TB. Now
VAS acts as layer of abstraction an intermediate .Instead of all request directly mapping to physical memory it first maps to VAS and then mapped to physical memory so that it can manage request for memory in more coordinated fashion than allowing process
to do it ,if not it will soon cause memory crunch.Any process when created on windows will see virtual memory according to its VAS limit.
Please read
This Article for detailed information
Please mark this reply as answer if it solved your issue or vote as helpful if it helped so that other forum members can benefit from it
My Technet Wiki Article
MVP -
Index is not used (why and what should i do) table too big
hi guys,
having a headache now. (on 10gR2 on linux system)
I used to have a large table and this is how i managed it. (i am on standard edition (thus i have no partitioning)
i would have a
1) cron job run daily to keep track of the lowest and highest ID of the table PER MONTH (inserted into a table)
2) below is the table
CDR MONTH 01-AUG-11 00:00:00 94118236 97584656
CDR MONTH 01-SEP-11 00:00:00 97581362 100573669
CDR MONTH 01-OCT-11 00:00:00 100570865 103631203
CDR MONTH 01-NOV-11 00:00:00 103629760 106497084
CDR MONTH 01-DEC-11 00:00:00 106494085 107306335
so as you can see, for the month of dec for example, the lowest CDR is 10649408 and the highest is 107306335.
3) so everytime i write a sql on this table if i want to get data for NOV
select * from cdr where ID >= get_cdr_id('CDR','NOV','SMALLEST');
and it would be
select * from cdr where ID >= 103629760;
In the past, the index will be used (index range scan), but now the optimiser is doing a FTS and is taking too much time.
therefore i went to force the index
select /*+INDEX(C, CDR_PK)*/* from cdr C where cdr_id > 103629760 and cdr_id < 106497084;
and the COST -> 1678927 (CDR, INDEX_ROWID)
13158 (CDR_PK, RANGE SCAN)
-- the result return is fast and good.
without the index
select * from cdr C where cdr_id > 100570865 and cdr_id < 103631203
the COST -> 440236 (CDR,FULL)
-- but the result return is slow like anything
My question is
1) which cost should i look at ?
the one with index hint have much higher COST, but the results return are so FAST.
1678927 (with hint) compare with 440236 (FTS)
2) is using the index is the correct way, why isnt my optimiser using it ?! how do i make the optimiser used it ?
Regards,
NoobIordan Iotzov wrote:
About the clustering factor– I think there are two possibilities:
1) The “clustering factor” is generally correct, i.e. it represents the true value of how the data is “scattered” through the table. The clustering factor for the fragment of data you are interested in (where cdr_id > 100570865 and cdr_id < 103631203), however, is different (smaller).
2)Oracle did not compute the “clustering factor” correctly. It is not uncommon occurrence, particularly in 10g. This blog entry by Randolf Geist is quite informative - http://oracle-randolf.blogspot.com/2010/01/clusteringfactor-what-if-analysis.html. Comprehensive information on that topic is available in Jonathan Lewis’ book Cost Based Oracle Fundamentals (chapter 5).
You can make the index more attractive by setting lower “clustering factor” value using DBMS_STATS.SET_INDEX_STATS. If you choose to do that, you should review your whole stats gathering procedure, because the next gathering would most likely reset the “clustering factor” to its old (high) value.
Iordan Iotzov
http://iiotzov.wordpress.com/ -
I'm trying to send music, scores and audio, as e-mail attachments, with a copy to my e-mail address. Whether I use .mus, .pdf, or .mp3, the error message says Preview doesn't recognize the file format. I haven't seen Preview, or had any problems, before now. Thanks for any suggestions.
Hi,
Firstly, your country is detemined by several factors, including your phone's regional settings, your SIM card and your NokiaAccount settings, if you used this phone whilst abroad then you may need to check that your regional and account settings are up to date since you have arrived in Canada.
For services like Gigs, you should also ensure that the MixRadio app has access to your phone's GPS location as well as the main location being on in the phone settings. To check this, as well as Location being turned on in the phone settings, in MixRadio itself go to Settings>Location>On:
The concern with favourites may also be related to location, if the music from certain artists is available in Canada but not where the service might think you are, availability of content may vary from region to region.
If all settings in both the phone, your Nokia Account and the MixRadio app are correct, we may have to investigate deeper.
It is impossible to comment on your camera without seeing it, you cold have the phone checked by Nokia Care locally, but of course if it was supplied in Europe it will be covered by the European Limited Warranty which is not valid in Canada.
If this or any post answers your question, please remember to help others by pressing the 'Accept as solution' button. -
How can i know which index will be used when executing the query ?
1 ) I have query in which i have 3-4 tables but there multiple index on one column .
so how can i know which index will be used when executing the query ?
2) I have a query which ia taking too much time . how can i know which table is taking too much time ?
3) Please Provide me some document of EXplain plan ?Hi Jimmy,
Consider the below example
/* Formatted on 2011/02/04 21:59 (Formatter Plus v4.8.8) */
CREATE TABLE FIRST AS
SELECT * FROM all_objects;
UPDATE FIRST
SET object_name = 'TEST'
WHERE owner != 'SCOTT';
CREATE INDEX idx_first ON FIRST(object_name);
SELECT *
FROM FIRST
WHERE object_name = 'TEST';
It has not used index
Execution Plan
Plan hash value: 2265626682
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 58678 | 7334K| 163 (4)| 00:00:02 |
|* 1 | TABLE ACCESS FULL| FIRST | 58678 | 7334K| 163 (4)| 00:00:02 |
/* Formatted on 2011/02/04 21:59 (Formatter Plus v4.8.8) */
SELECT *
FROM FIRST
WHERE object_name = 'emp';
This has used the index
Execution Plan
Plan hash value: 1184810458
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 128 | 1 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| FIRST | 1 | 128 | 1 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IDX_FIRST | 1 | | 1 (0)| 00:00:01 |
From this we can come to the conclusion that, whether to use one index or not by oracle
would also depend on the data which is present in the table. This has to be this way as
we see in the bind peeking, if oracle sticks to only one plan, say only use the full table
scan, it would be a performance hit when it searches for the second query ie where object_name
='emp';
2.
If we have a query like below.
select * from emp
where upper(ename) = upper(:p_ename);
Evenif we have the index on ename column, oracle wouldn't be able to use the index, as there is a function in the predicate column. If you need oracle to use the index, we need to create a function based index as below.
Create index idx_ename on emp(upper(ename));
Regards,
Cool -
How to assure index is being used for Query
Hi All,
Indexed are best way to speedup the data retrieval process selectively.
however i wanted to how to trace that weather index is being used in a particular query.
1. Table tab1 has composite index on a and b.
2. Select a,b,c from tab1 where a>500 ;
Will this query use index create from 1 ?
Conceptually it should not because where as part contains only field A where as index is composit on field A and B.
However , i wanted to know to trace that a perticual query is using index or not ?
This question was asked to me in an interview.
Pls le me know at [email protected]
Thanks in Advance
AlokHi,
Use explain plan to know if index is use.
As you can see in the following example, even if index is composed and I use only a part in query, index can be used :
SQL> create table test (col1 number, col2 number, col3 varchar2(10));
Table created.
SQL> insert into test select object_id, data_object_id, substr(object_name,1,10) from dba_objects;
70211 rows created.
SQL> create index idx on test(col1,col2);
Index created.
SQL> explain plan for
2 select col1,col2,col3 from test where col1 > 500;
Explained.
SQL> @$ORACLE_HOME/rdbms/admin/utlxpls
PLAN_TABLE_OUTPUT
| Id | Operation | Name | Rows | Bytes | Cost |
| 0 | SELECT STATEMENT | | | | |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST | | | |
|* 2 | INDEX RANGE SCAN | IDX | | | |
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
2 - access("TEST"."COL1">500)
filter("TEST"."COL1">500)
Note: rule based optimization
16 rows selected.
--If stats are collected, index is no more used
SQL> analyze table test compute statistics;
SQL> explain plan for
2 select col1,col2,col3 from test where col1 > 500;
Explained.
SQL> @$ORACLE_HOME/rdbms/admin/utlxpls
PLAN_TABLE_OUTPUT
| Id | Operation | Name | Rows | Bytes | Cost |
| 0 | SELECT STATEMENT | | 69808 | 1227K| 16 |
|* 1 | TABLE ACCESS FULL | TEST | 69808 | 1227K| 16 |
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
1 - filter("TEST"."COL1">500)
Note: cpu costing is off
14 rows selected.
--But if you use an equlity in your query instead of >, index is still used
SQL> explain plan for
2 select col1,col2,col3 from test where col1 = 500;
Explained.
SQL> @$ORACLE_HOME/rdbms/admin/utlxpls
PLAN_TABLE_OUTPUT
| Id | Operation | Name | Rows | Bytes | Cost |
| 0 | SELECT STATEMENT | | 1 | 18 | 3 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST | 1 | 18 | 3 |
|* 2 | INDEX RANGE SCAN | IDX | 1 | | 2 |
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
2 - access("TEST"."COL1"=500)
Note: cpu costing is off
15 rows selected.
SQL> Nicolas. -
Index isn't used when specifying IS NULL
Hello,
I'm using Oracle 10.2.0.4. When I run this statement, the explain plan shows that a composite index is used which is expected.
select * from isis.cour_off where orga_# = 4
However, when I run the following statement, the explain plan shows FULL TABLE SCAN:
select * from isis.cour_off where orga_# IS NULL
Is this to be expected? If so, then why?Centinul wrote:
If I had to wager a guess it's probably because the OP is selecting all the columns anyways so it's probably more efficient to use multi-block reads to retrieve the entire rows from the table. However, that's hard to say without data.Not really. It is not data what drives optimizer to use index or not in the first stage. In case of single column index main question is: is column NULLable? But, as you noted, OP has composite index . Therefore, question "is column NULLable" transforms into are all index columns NULLable? If they are - index can't be used no matter what, since it is possible table has rows where all index columns are NULL and therefore there will be no index entry for such row. If at least one index column is NOT NULL, index can be (doesn't mean will be) used:
SQL> create table tbl
2 as
3 select level id,case mod(level,1000) when 0 then to_number(null) else level end val from dual connect by level <= 100000;
Table created.
SQL> create index tbl_idx on tbl(val,id);
Index created.
SQL> exec dbms_stats.gather_table_stats('SCOTT','TBL');
PL/SQL procedure successfully completed.
SQL> explain plan for select * from tbl where val is null;
Explained.
SQL> @?\rdbms\admin\utlxpls
PLAN_TABLE_OUTPUT
Plan hash value: 2144214008
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 100 | 900 | 53 (8)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| TBL | 100 | 900 | 53 (8)| 00:00:01 |
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
1 - filter("VAL" IS NULL)
13 rows selected.
SQL> alter table tbl modify id not null;
Table altered.
SQL> explain plan for select * from tbl where val is null;
Explained.
SQL> @?\rdbms\admin\utlxpls
PLAN_TABLE_OUTPUT
Plan hash value: 2817369304
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 100 | 900 | 2 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| TBL_IDX | 100 | 900 | 2 (0)| 00:00:01 |
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
1 - access("VAL" IS NULL)
13 rows selected.
SQL> As you can see, even though column ID did not have any NULL values index wasn't used since potentially ID can be null. As soon as column ID was set to NOT NULL optimizer started using index.
SY. -
Info on whether to use ext. Netegrity tool or the default provided by SAP
Hi,
Can anyone give me some info. as to which would be better or which would SAP recommend as Best Practice - whether to use external <b>Netegrity tool for Authentication & Security</b> or the default provided by SAP Web AS.
Thanks & Regards,
JeetuFirstly, I completely agree with Nicks comments and in any case the original question was Best Practice and desgin phase not technical "how to" implemenation.
@Jeetendra,
Actually, overall the decisions are normally made for you as a basic project requirement eg. Constraint: Users need to access Portal from a web link in intranet site secured by Netegrity without reauthentication. So as mentioned above its usually a pure SSO constraint. Thereafter it is more of 'How best' and what are the technical limitations. Otherwise there is no real need to make life more difficult. Could you describe why you are having to make this feasability study?
Since Netegrity is an external component, Performance will never be a reason to include Netegrity as it only adds complexity. The performance impact will depend on agent configuration and policies and size of Netegrity infrastructure etc. This needs to be evaluated with the Netegrity team based on the estimated number of concurrent users/requests etc. Concrete info will not be possible unless you do a load test with / without Netegrity and compare results.
Security aspects have to be looked at across the whole spectrum based on the local environment and requirements. Netegrity is complementary to WAS security but can actually reduce security eg. If basic header authentication is configured without additional checks. It also may or may not be required to cover requests to back end systems.
Take a look at the SAP security guide.
If you are still unsure of how best to proceed you may need to get specialist assistance as I doubt someone will be able/willing to provide the detail you require without some kind of intervention. -
How can I determine whether to use an event structure or a case structure?
I'm starting a large project and need a state machine. I can't decide on whether to use a case structure or event structure. Is there an article or other information that describes criteria for selecting between the two approaches?
Thank you,
Chuck
Solved!
Go to Solution.Hi Chuck,
Well case structures and event structures differ quite alot. Here's a link for indepth information on Event Structures, and using them in state machines: http://zone.ni.com/devzone/cda/tut/p/id/2962. Hopefuly this will help you make up your mind.
Let me know if you have any questions after reading it.
Regards,
Dominic Walker
Cardiff University
Electrical and Electronic Engineering Student -
I have a question about Lightroom 5... I used it last night, I go to get on it today and its will not open. I have an error msg "Lightroom encountered an error when reading from its preview cache and needs to quit" Lightroom will attempt to fix the problem when reopened
https://forums.adobe.com/message/6219922#6219922
See if the issue in the thread above helps you to solve your problem. -
Need suggestion whether to use ATM or MPLS in DSL implementation
Presently i am working in ISP, and we are providing internet access via simple dialup, ISDN and IVS. and now we want to implement DSL i ve talk with few peoples regarding whether to use ATM or MPLS in DSL implementation but because they are solution providers so i think they are giving me expensive solution. as long as i know about this is,whole world is shifting from ATM to MPLS Technology. ATM implementation cost is very high. so i need suggestion from u because you also have practical exposure.
I believe ATM is soon getting obsolete...
-
Index not being used in Select statement
Friends
I have the following SQL statement:
SELECT
a.acct,
a.date_field,
UPPER(b.feegroup) feegrp,
SUM (a.fee1) fee1,
SUM (a.fee2) fee2,
SUM (a.fee3) fee3
FROM table1 a, table2 b
WHERE 1 = 1
AND a.fee_id = b.fee_id
GROUP BY a.acct, a.date_field, b.feegroup;
Both the tables have index on fee_id column. When I run the explain plan for this statement, I am getting the following output:
Operation | Option | Object Name | Position
SELECT STATEMENT | | | 560299
HASH | GROUP BY| |1
TABLE ACCESS | FULL| table2 | 1
TABLE ACCESS | FULL| table1 | 2
Why Oracle is not using the index?
Edited by: darshilm on Dec 10, 2009 3:56 PMThe proposed plan is the optimal according to your current conditions in the "where clause" where you have only the equality join condition and therefore the CBO can use HASH JOIN. Using any kind of index access would just increase the amount of required work unless you would add some very restrictive conditions which will select rows from relatively small amount of blocks. Here I have to mention that what really counts in the CBO cost calculation is the amount of blocks accessed and not the number of rows. The "currency" for I/O in Oracle is a block and not a row. CBO always uses an assumption that there is nothing in the buffer cache and it will have to perform a physical read for every block.
How many blocks will actually be accessed depends on the data distribution. It can happen that every single row that you have to retrieve resides in a different block and although you access only 1000 rows out of a million row table you would have to visit almost every block of that table. For such a situation a FULL TABLE SCAN is the best access path and Oracle will use multiblock I/O for that. On the other side you can have those 1000 rows only in a few blocks and then the index access would be the most appropriate one. For index access Oracle uses single block I/O. Usually the actual situation is somewhere between this two extreme situations. But you can run some tests by yourself and see when an index access will be replaced by a full table scan while you will make your predicates less selective.
HTH, Joze
Co-author of the forthcoming book "Expert Oracle Practices"
http://www.apress.com/book/view/9781430226680
Oracle related blog: http://joze-senegacnik.blogspot.com/
Blog about flying: http://jsenegacnik.blogspot.com/
Blog about Building Ovens, Baking and Cooking: http://senegacnik.blogspot.com -
Why index is not used by this table
Dear all,
Currently I'm facing problem with tuning one sql statement.
It shows that full table scan in ZTLTBC_FILTER cost 15:19.
But in table ZTLTBC_FILTER, it have index with field
index 1 MANDT INT_NAME FNAME VALUE
index 2 MANDT EXEC_ID COUNTER
index 3 MANDT INT_NAME VALUE
the last statistic date for these index is three months before
Could you please help to find out the reason why index is not used? statistics are old or small distinct value for field INT_NAME?
How to solve this full table scan problem?
Thanks & Regards,
Chris
sql statement
SELECT T_00."MANDT",T_00."EXEC_ID",T_00."COUNTER",T_00."FNAME",T_00."INT_NAME",T_00."VALUE"
FROM "ZTLTBC_FILTER" T_00
WHERE T_00."MANDT"=:A0 AND T_00."INT_NAME"=:A1 AND EXISTS
(SELECT T_100."INT_NAME"
FROM "ZTLTBC_MIRR_BUFF" T_100
WHERE T_100."MANDT"=:A2 AND T_100."INT_NAME"=:A3 AND T_100."EXEC_ID"=T_00."EXEC_ID" AND
T_100."COUNTER"=T_00."COUNTER")
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | | | | 176K(100)| |
|* 1 | HASH JOIN RIGHT SEMI| | 9958K| 1111M| 598M| 176K (2)| 00:17:53 |
|* 2 | INDEX RANGE SCAN | ZTLTBC_MIRR_BUFF~0 | 9958K| 484M| | 6265 (1)| 00:00:39 |
|* 3 | TABLE ACCESS FULL | ZTLTBC_FILTER | 13M| 822M| | 150K (2)| 00:15:19 |
1 - access("T_100"."EXEC_ID"="T_00"."EXEC_ID" AND "T_100"."COUNTER"="T_00"."COUNTER")
2 - access("T_100"."MANDT"=:A2 AND "T_100"."INT_NAME"=:A3)
3 - filter(("T_00"."INT_NAME"=:A1 AND "T_00"."MANDT"=:A0))Hello Bret,
I'm using oracle 11.2
Thanks & Regards,
Chris
Maybe you are looking for
-
SOA WSDL service deployment error
I am getting this error while deploying the web services. I added a service in the WSDL like this and it is not working. <wsdl:service name="DataFeedService"> <wsdl:port name="receive_ptt" binding="tns:receive_pttBinding"> <soap:address location="htt
-
IPhone purchase via Sprint & fees particular to Sprint for that purchase?
Hi -- I hope it's appropriate to post this question here. I suppose I could post it on the Sprint site as well, but folks on here, in my experience, generally know what's what. I went through the checkout process to purchase an iPhone 4S via Sprint
-
Touch down event on a UIImageView
Hi, Is there a way to catch the Touch Down event on an UIImageView?
-
Using Oracle Forms Developer/Services 6i Release 2 with Oracle 9i
Hello, I am trying to load Oracle Forms Developer/Services 6i Release 2 for Windows 95/98/NT/2000/XP with already installed Oracle 9i , I am able to use all the applications installed with 9i database but I am not able to use Forms with it, Please le
-
Dear SDN Members, I am using EP 7.0 SP 14 Where in UWL Inbox i can see refresh link.But i want button and Reverse Button to be added in UWL Link and i want to remove assign to me button. Please help me Thanks KV