I have recently upgraded a third party application from Oracle 8.1.6 to Oracle 9.2.0.7.0 and all is well apart from a couple of queries that are running poorly. The queries are based on a simple view and I am having problems seeing why the cost based optimiser is behaving as it is with it.
When i run the uderlying query of the view as a SQL statement it gives me a high cost but if I strip out the column list (keeping the rest of the query consitent) it behaves much better. Here are the plans from the 2 versions of the query:
Original Query
----------------
Explain Plan
Set STATEMENT_ID='GJC3'
For
SELECT IF_.R_OBJECT_ID,IF_.OBJECT_NAME
,IF_.R_OBJECT_TYPE,IF_.TITLE
,IF_.SUBJECT,IF_.A_APPLICATION_TYPE
,IF_.A_STATUS,IF_.R_CREATION_DATE,IF_.R_MODIFY_DATE,IF_.R_MODIFIER
,IF_.R_ACCESS_DATE,IF_.A_IS_HIDDEN,IF_.I_IS_DELETED,IF_.A_RETENTION_DATE
,IF_.A_ARCHIVE,IF_.A_COMPOUND_ARCHITECTURE,IF_.A_LINK_RESOLVED,IF_.I_REFERENCE_CNT
,IF_.I_HAS_FOLDER,IF_.R_LINK_CNT,IF_.R_LINK_HIGH_CNT,IF_.R_ASSEMBLED_FROM_ID
,IF_.R_FRZN_ASSEMBLY_CNT,IF_.R_HAS_FRZN_ASSEMBLY,IF_.I_CONTENTS_ID,IF_.A_CONTENT_TYPE,IF_.R_PAGE_CNT
,IF_.R_CONTENT_SIZE,IF_.A_FULL_TEXT,IF_.A_STORAGE_TYPE,IF_.I_CABINET_ID
,IF_.OWNER_NAME,IF_.OWNER_PERMIT,IF_.GROUP_NAME,IF_.GROUP_PERMIT,IF_.WORLD_PERMIT,IF_.I_ANTECEDENT_ID,IF_.I_CHRONICLE_ID,IF_.I_LATEST_FLAG,IF_.R_LOCK_OWNER,IF_.R_LOCK_DATE,IF_.R_LOCK_MACHINE,IF_.LOG_ENTRY,IF_.I_BRANCH_CNT,IF_.I_DIRECT_DSC,IF_.R_IMMUTABLE_FLAG,IF_.R_FROZEN_FLAG,IF_.R_HAS_EVENTS,IF_.ACL_DOMAIN,IF_.ACL_NAME,IF_.A_SPECIAL_APP,IF_.DOCUMENT_NUMBER,IF_.DOCUMENT_DATE,IF_.ISSUE_LEVEL
,IF_.I_IS_REFERENCE
,IF_.RESOLUTION_LABEL
,IF_.R_IS_VIRTUAL_DOC
,IF_.R_IS_PUBLIC
,IF_.R_CREATOR_NAME
,IF_.R_POLICY_ID
,IF_.R_RESUME_STATE
,IF_.R_CURRENT_STATE
,IF_.R_ALIAS_SET_ID
,IF_.I_IS_REPLICA
,IF_.A_CATEGORY
,IF_.LANGUAGE_CODE
,IF_.I_VSTAMP
,UY_.DCA_IDENTIFIER
,UY_.DCA_CURRENT_STATUS
,UY_.DCA_PROJECT
,UY_.DCA_DATE_OPENED
,UY_.DCA_DESCRIPTION
,UY_.DCA_FORMAL
,UY_.DCA_WORKFLOW_ID
,UY_.DCA_SUBMITTED
,UY_.DCA_DESTINATION
,UY_.DCA_PUBLISHING_INFO
,UY_.DCA_LOCKOWNER
,UY_.DCA_REJECTION_NOTES
,UY_.DCA_FINALISED_DATE
,UY_.DCA_FORMAL_START_DATE
,UY_.ACTIVE_REVIEWERS
FROM LMREDMS.dm_sysobject_s IF_
,LMREDMS.lm_dca_s UY_
WHERE IF_.R_OBJECT_ID=UY_.R_OBJECT_ID
/
Query Plan
--------------------------------------------------------------------------------
1.33774 SELECT STATEMENT GJC3 Cost=33774
--2.1 HASH JOIN
--3.1 TABLE ACCESS FULL LM_DCA_S
--3.2 TABLE ACCESS FULL DM_SYSOBJECT_S
Column list removed
-----------------------
Explain Plan
Set STATEMENT_ID='GJC3'
For
SELECT IF_.R_OBJECT_ID
,UY_.R_OBJECT_ID
FROM LMREDMS.dm_sysobject_s IF_
,LMREDMS.lm_dca_s UY_
WHERE IF_.R_OBJECT_ID=UY_.R_OBJECT_ID
/
Query Plan
--------------------------------------------------------------------------------
1.289 SELECT STATEMENT GJC3 Cost=289
--2.1 NESTED LOOPS
--3.1 INDEX FAST FULL SCAN D_1F004421800001A1 UNIQUE
--3.2 INDEX UNIQUE SCAN D_1F00442180000108 UNIQUE
Can anyone tell me why the first query with all the columns listed takes so much longer than the second. All tables are analyzed and the optimizer rule is set to "Choose. The DM_SYSOBJECTS_S table contains about 1,600,000 rows and the LM_DCA_S table about 33,000. Both tables have an index on the R_OBJECT_ID column
Thanks in advance
Chedgey
by: MohanKNairPosted on 2006-09-18 at 04:48:39ID: 17542534
The columns IF_.R_OBJECT_ID and UY_.R_OBJECT_ID are available in the index itself, so no table access required. When there are other columns, table access is required. The query is making use of HASH JOIN.
NESTED LOOPS can be used only if there are indexes available for either IF_.R_OBJECT_ID or UY_.R_OBJECT_ID