Kbase P78607: Find first statement or any query for Oracle dataserver performs slow
Autor |
  Progress Software Corporation - Progress |
Acesso |
  Público |
Publicação |
  9/19/2008 |
|
Status: Verified
SYMPTOM(s):
Find statement for Oracle DataServer performs slow
Any query statement (find, for first, for each) performs slow
The SQL generated by DataServer 99% percent of the time will cause Oracle do a full table scan
The index hints are correctly generated and sent over to Oracle
The Oracle's query plans shows a full table scan
The Oracle's query plan is seen via tracing and tkprof
Example SQL and query plan (against account table):
4GL
FIND FIRST account USE-INDEX label_i NO-LOCK NO-ERROR.
SELECT /*+ INDEX_ASC(T0 ACCOUNT##LABEL_I) */ PROGRESS_RECID
FROM
TM.ACCOUNT T0 order by U##ORG, U##ACCLABEL
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.01 0.01 0 0 0 0
Execute 2 0.17 0.18 0 0 7 0
Fetch 1 53.31 287.12 36481 13212 2509 20
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 53.49 287.31 36481 13212 2516 20
Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 23 (TM)
Rows Row Source Operation
------- ---------------------------------------------------
20 SORT ORDER BY
1327211 TABLE ACCESS FULL ACCOUNT
Rows Execution Plan
------- ---------------------------------------------------
0 SELECT STATEMENT GOAL: CHOOSE
20 SORT (ORDER BY)
1327211 TABLE ACCESS (FULL) OF 'ACCOUNT'
********************************************************************************
SELECT /*+ INDEX(T0 ACCOUNT##PROGRESS_RECID) */ U##ACCLABEL,ACCLABEL,ACC1,
ACC2,ACC3,ACC4,ACC5,ACC6,ACC7,ACC8,ACC9,ACC10,U##ORG,ORG,U##REF_VALUE,
REF_VALUE,progress_recid
FROM
TM.ACCOUNT T0 WHERE PROGRESS_RECID = :rid
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 0 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.00 0.00 0 4 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.00 0.00 0 4 0 1
Misses in library cache during parse: 0
Optimizer goal: CHOOSE
Parsing user id: 23 (TM)
Rows Execution Plan
------- ---------------------------------------------------
0 SELECT STATEMENT GOAL: CHOOSE
0 TABLE ACCESS (BY INDEX ROWID) OF 'ACCOUNT'
0 INDEX (UNIQUE SCAN) OF 'ACCOUNT##PROGRESS_RECID' (UNIQUE)
********************************************************************************
FACT(s) (Environment):
Oracle DataServer
Oracle 8.x
All Supported Operating Systems
Progress 9.x
OpenEdge 10.x
CAUSE:
This is more an Oracle issue than dataserver issue. As hints are correctly generated and passed to Oracle, Oracle is not picking up the hint and use index to look up the record but instead does a full table scan
FIX:
To accomodate Oracle's behavior against Index hint, use a fake where clause in find statement so the SQL generated has a where clause, Oracle then will use index.
Sample 4GL code and SQL code
FIND FIRST account WHERE account.org = account.org
USE-INDEX label-i NO-LOCK NO-ERROR.
TKPROF: Release 8.1.6.0.0 - Production on Wed Apr 28 08:54:24 2004
(c) Copyright 1999 Oracle Corporation. All rights reserved.
Trace file: gtm82d_ora_5548.trc
Sort options: default
********************************************************************************
count = number of times OCI procedure was executed
cpu = cpu time in seconds executing
elapsed = elapsed time in seconds executing
disk = number of physical reads of buffers from disk
query = number of buffers gotten for consistent read
current = number of buffers gotten in current mode (usually for update)
rows = number of rows processed by the fetch or execute call
********************************************************************************
ALTER SESSION SET SQL_TRACE TRUE
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 0 0.00 0.00 0 0 0 0
Execute 1 0.00 0.03 0 0 0 0
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 1 0.00 0.03 0 0 0 0
Misses in library cache during parse: 0
Optimizer goal: CHOOSE
Parsing user id: 23 (TM)
********************************************************************************
SELECT /*+ INDEX_ASC(T0 ACCOUNT##LABEL_I) */ PROGRESS_RECID
FROM
TM.ACCOUNT T0 WHERE ((U##ORG = U##ORG)) order by U##ORG, U##ACCLABEL
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.01 0.01 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.00 0.00 0 3 0 20
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3 0.01 0.01 0 3 0 20
Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 23 (TM)
Rows Execution Plan
------- ---------------------------------------------------
0 SELECT STATEMENT GOAL: CHOOSE
0 INDEX GOAL: ANALYZED (FULL SCAN) OF 'ACCOUNT##LABEL_I' (UNIQUE)
********************************************************************************
SELECT /*+ INDEX(T0 ACCOUNT##PROGRESS_RECID) */ U##ACCLABEL,ACCLABEL,ACC1,
ACC2,ACC3,ACC4,ACC5,ACC6,ACC7,ACC8,ACC9,ACC10,U##ORG,ORG,U##REF_VALUE,
REF_VALUE,progress_recid
FROM
TM.ACCOUNT T0 WHERE PROGRESS_RECID = :rid
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 0 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.00 0.00 0 4 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.00 0.00 0 4 0 1
Misses in library cache during parse: 0
Optimizer goal: CHOOSE
Parsing user id: 23 (TM)
Rows Execution Plan
------- ---------------------------------------------------
0 SELECT STATEMENT GOAL: CHOOSE
0 TABLE ACCESS GOAL: ANALYZED (BY INDEX ROWID) OF 'ACCOUNT'
0 INDEX GOAL: ANALYZED (UNIQUE SCAN) OF
'ACCOUNT##PROGRESS_RECID' (UNIQUE)