欢迎投稿

今日深度:

【Oracle】CBO版本带来的视图INVALID

【Oracle】CBO版本带来的视图INVALID


源端:Oracle 11.1.0.7

目标端:Oracle 11.2.0.4

最近做的一个数据迁移的CASE中遇到的问题,一个VIEW在完成数据迁移后由VALID的状态变为了INVALID。

从源库中使用get_ddl拿到的该VIEW创建语句如下:

CREATE OR REPLACE FORCE VIEW "APPS"."IGW_BUDGET_CATEGORY_V1" ("PROPOSAL_ID", "VERSION_ID", "BUDGET_PERIOD_ID", "LINE_ITEM_ID", "EXPENDITURE_TYPE", "EXPENDITURE_CATEGORY_FLAG", "BUDGET_CATEGORY_CODE", "BUDGET_CATEGORY", "BASE_AMT", "OH_APPLIED_FLAG", "OH_COST", "EB_COST") AS

SELECT pbcv.proposal_id , pbcv.version_id , pbcv.budget_period_id , pbcv.line_item_id , pbcv.expenditure_type , pbcv.expenditure_category_flag , pbcv.budget_category_code , fl.meaning budget_category , sum(pbcv.line_item_cost+pbcv.eb_cost) base_amt , decode(pbcv.oh_cost, 0,'N', 'Y') oh_applied_flag , pbcv.oh_cost , pbcv.eb_cost

from igw_budget_complete_v pbcv , igw_lookups_v fl

WHERE pbcv.budget_category_code = fl.lookup_code and fl.lookup_type = 'IGW_BUDGET_CATEGORY'

group by pbcv.proposal_id, pbcv.version_id, pbcv.budget_period_id ,pbcv.budget_category_code, fl.meaning, pbcv.line_item_id, pbcv.expenditure_type ,pbcv.expenditure_category_flag;

拿到该语句进行了查看发现该语句本身就存在问题,理论上无论哪个数据库版本都无法运行才对,在group by当中缺少了pbcv.oh_cost 、pbcv.eb_cost两列,但问题就是为何在源库(11.1.0.7)当中不存在问题,而目标库(11.2.0.4)当中存在问题呢?当时做case的时候直接选择了认为是一个BUG,改写了SQL,但一直心存疑惑。这两天终于搞明白了这个问题,原来是由于CBO版本导致的。

首先我们来看一下源库(11.1.0.7)版本中创建view的该sql语句的执行计划:

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------



-------------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|

-------------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 156 | 5 (20)|

| 1 | HASH GROUP BY | | 1 | 156 | 5 (20)|

| 2 | NESTED LOOPS | | | | |

| 3 | NESTED LOOPS | | 1 | 156 | 4 (0)|

| 4 | TABLE ACCESS FULL | IGW_BUDGET_DETAILS | 1 | 88 | 2 (0)|

|* 5 | INDEX RANGE SCAN | FND_LOOKUP_VALUES_U1 | 1 | | 2 (0)|

|* 6 | TABLE ACCESS BY INDEX ROWID| FND_LOOKUP_VALUES | 1 | 68 | 2 (0)|

-------------------------------------------------------------------------------------------



Predicate Information (identified by operation id):

---------------------------------------------------



5 - access("LOOKUP_TYPE"='IGW_BUDGET_CATEGORY' AND "VIEW_APPLICATION_ID"=0 AND

"BUDGET_CATEGORY_CODE"="LOOKUP_CODE" AND "LANGUAGE"=USERENV('LANG'))

filter("LANGUAGE"=USERENV('LANG') AND

"SECURITY_GROUP_ID"="FND_GLOBAL"."LOOKUP_SECURITY_GROUP"("LV"."LOOKUP_TYPE","LV"."V

IEW_APPLICATION_ID"))

6 - filter("ENABLED_FLAG"='Y' AND ("END_DATE_ACTIVE" IS NULL OR

"END_DATE_ACTIVE">=SYSDATE@!) AND "START_DATE_ACTIVE"<=SYSDATE@!)

 

该查询实际上是基于两个表IGW_BUDGET_DETAILS、FND_LOOKUP_VALUES 的查询。经过查看其它信息发现sql语句中未加入到group by当中的pbcv.oh_cost 、pbcv.eb_cost两列均为对于表IGW_BUDGET_DETAILS中列line_item_id处理后得到的结果。

针对这种情况进行猜想,该sql语句在源库(11.1.0.7)能成功执行的原因是否是因为:在sql语句进行语法检查后CBO对该sql语句进行查询转换,最终转换结果中的select语句中并不包含pbcv.oh_cost 、pbcv.eb_cost,而是line_item_id列的信息,所以该语句最终执行成功。而在目标库(11.2.0.4)中由于CBO版本不同,查询转换结果不同导致了该问题。

那么下面尝试一下修改目标库的CBO版本,然后执行该语句:

SQL> alter system set optimizer_features_enable='11.1.0.7';



System altered.



SQL> CREATE OR REPLACE FORCE VIEW "APPS"."IGW_BUDGET_CATEGORY_V1" ("PROPOSAL_ID", "VERSION_ID", "BUDGET_PERIOD_ID", "LINE_ITEM_ID", "EXPENDITURE_TYPE", "EXPENDITURE_CATEGORY_FLAG", "BUDGET_CATEGORY_CODE", "BUDGET_CATEGORY", "BASE_AMT", "OH_APPLIED_FLAG", "OH_COST", "EB_COST") AS

SELECT pbcv.proposal_id , pbcv.version_id , pbcv.budget_period_id , pbcv.line_item_id , pbcv.expenditure_type , pbcv.expenditure_category_flag , pbcv.budget_category_code , fl.meaning budget_category , sum(pbcv.line_item_cost+pbcv.eb_cost) base_amt , decode(pbcv.oh_cost, 0,'N', 'Y') oh_applied_flag , pbcv.oh_cost , pbcv.eb_cost

2 3 from igw_budget_complete_v pbcv , igw_lookups_v fl

4 WHERE pbcv.budget_category_code = fl.lookup_code and fl.lookup_type = 'IGW_BUDGET_CATEGORY'

5 group by pbcv.proposal_id, pbcv.version_id, pbcv.budget_period_id ,pbcv.budget_category_code, fl.meaning, pbcv.line_item_id, pbcv.expenditure_type ,pbcv.expenditure_category_flag;



View created.

可以看到在降低CBO版本后视图成功创建,果然是CBO版本导致的。

当然这个最终的解决方法还是要改写SQL,但终于弄明白了其导致原因,并不是什么BUG,而是由于CBO版本不同,查询转换结果不同导致的。在此记录一下,也希望能给遇到同样问题的兄弟解解惑~

 

 

www.htsjk.Com true http://www.htsjk.com/oracle/23015.html NewsArticle 【Oracle】CBO版本带来的视图INVALID 源端:Oracle 11.1.0.7 目标端:Oracle 11.2.0.4 最近做的一个数据迁移的CASE中遇到的问题,一个VIEW在完成数据迁移后由VALID的状态变为了INVALID。 从源库中使用...
评论暂时关闭