谢谢.
使用Oracle 10g我有一个简单的查询视图定义如下
create or replace vIEw v_test as select distinct u.bo_ID as bo_ID,upper(trim(d.dept_ID)) as dept_ID from cust_bo_users u join cust_bo_roles r on u.role_name=r.role_name join cust_dept_roll_up_tbl d on (r.region is null or trim(r.region)=trim(d.chrgback_reg)) and (r.prod_ID is null or trim(r.prod_ID)=trim(d.prod_ID)) and (r.div_ID is null or trim(r.div_ID)=trim(d.div_ID )) and (r.clus_ID is null or trim(r.clus_ID )=trim( d.clus_ID)) and (r.prod_ln_ID is null or trim(r.prod_ln_ID)=trim(d.prod_ln_ID)) and (r.dept_ID is null or trim(r.dept_ID)=trim(d.dept_ID))
定义为替换以下视图
create or replace vIEw v_bo_secured_detail select distinct Q.BO_ID,Q.DEPT_ID from (select U.BO_ID BO_ID,UPPER(trim(D.DEPT_ID)) DEPT_ID from CUST_BO_USERS U,CUST_BO_RolES R,CUST_DEPT_RolL_UP_TBL D where U.RolE_name = R.RolE_name and R.RolE_LEVEL = 'REGION' and trim(R.REGION) = UPPER(trim(D.CHRGBACK_REG)) union all select U.BO_ID BO_ID,CUST_DEPT_RolL_UP_TBL D where U.RolE_name = R.RolE_name and R.RolE_LEVEL = 'RG_PROD' and trim(R.REGION) = UPPER(trim(D.CHRGBACK_REG)) and trim(R.PROD_ID) = UPPER(trim(D.PROD_ID)) union all select U.BO_ID BO_ID,CUST_DEPT_RolL_UP_TBL D where U.RolE_name = R.RolE_name and R.RolE_LEVEL = 'PROD' and trim(R.PROD_ID) = UPPER(trim(D.PROD_ID)) union all select U.BO_ID BO_ID,CUST_DEPT_RolL_UP_TBL D where U.RolE_name = R.RolE_name and R.RolE_LEVEL = 'div' and trim(R.div_ID) = UPPER(trim(D.div_ID)) union all select U.BO_ID BO_ID,CUST_DEPT_RolL_UP_TBL D where U.RolE_name = R.RolE_name and R.RolE_LEVEL = 'RG_div' and trim(R.REGION) = UPPER(trim(D.CHRGBACK_REG)) and trim(R.div_ID) = UPPER(trim(D.div_ID)) union all select U.BO_ID BO_ID,CUST_DEPT_RolL_UP_TBL D where U.RolE_name = R.RolE_name and R.RolE_LEVEL = 'CLUS' and trim(R.CLUS_ID) = UPPER(trim(D.CLUS_ID)) union all select U.BO_ID BO_ID,CUST_DEPT_RolL_UP_TBL D where U.RolE_name = R.RolE_name and R.RolE_LEVEL = 'RG_CLUS' and trim(R.REGION) = UPPER(trim(D.CHRGBACK_REG)) and trim(R.CLUS_ID) = UPPER(trim(D.CLUS_ID)) union all select U.BO_ID BO_ID,CUST_DEPT_RolL_UP_TBL D where U.RolE_name = R.RolE_name and R.RolE_LEVEL = 'PROD_LN' and trim(R.PROD_LN_ID) = UPPER(trim(D.PROD_LN_ID)) union all select U.BO_ID BO_ID,UPPER(trim(R.DEPT_ID)) DEPT_ID from CUST_BO_USERS U,CUST_BO_RolES R where U.RolE_name = R.RolE_name and R.RolE_LEVEL = 'DEPT') Q
目标是删除对RolE_LEVEL列的依赖.
为简单起见,v_test的执行计划明显低于v_bo_secured_detail
select * from <vIEw> where bo_ID='value'
查询.并且在真实世界查询中使用时显着降低
select CT_REPORT.RPT_KEY,CT_REPORT_ENTRY.RPE_KEY,CT_REPORT_ENTRY.CUSTOM16,Exp_Sub_Type.value,min(CT_REPORT_PAYMENT_CONF.PAY_DATE),CT_REPORT.PAID_DATE from CT_REPORT,<VIEW> SD,CT_REPORT_ENTRY,CT_List_ITEM_LANG Exp_Sub_Type,CT_REPORT_PAYMENT_CONF,CT_STATUS_LANG Payment_Status where (CT_REPORT_ENTRY.RPT_KEY = CT_REPORT.RPT_KEY) and (Payment_Status.STAT_KEY = CT_REPORT.PAY_KEY) and (Exp_Sub_Type.li_KEY = CT_REPORT_ENTRY.CUSTOM9 and Exp_Sub_Type.LANG_CODE = 'en') and (CT_REPORT.RPT_KEY = CT_REPORT_PAYMENT_CONF.RPT_KEY) and (SD.BO_ID = 'JZHU9') and (SD.DEPT_ID = UPPER(CT_REPORT_ENTRY.CUSTOM5)) and (Payment_Status.name = 'Payment Confirmed' and (Payment_Status.LANG_CODE = 'en') and CT_REPORT.PAID_DATE > to_date('01/01/2008','mm/dd/yyyy') and Exp_Sub_Type.value != 'Korea') group by CT_REPORT.RPT_KEY,CT_REPORT.PAID_DATE
执行时间差异很大. v_test视图需要15个小时,而v_bo_secured_detail需要几秒钟.
谢谢所有回复的人
这是我要记住的一个.表达式的理论和数学符合基于硬件的执行的现实的地方.哎哟.
解决方法 如 the Oracle documentation says所示,成本是相对于特定执行计划的估计成本.调整查询时,相对于计算成本的特定执行计划可能会发生变化.有时戏剧性.v_test性能的问题在于Oracle除了执行嵌套循环之外无法执行它,对于每个cust_bo_roles,扫描所有cust_dept_roll_up_tbl以查找匹配项.如果表的大小为n和m,则需要n * m的时间,这对于大型表来说很慢.相比之下,v_bo_secured_detail被设置为一系列查询,每个查询都可以通过其他机制完成. (Oracle有一个它可以使用的数字,包括使用索引,动态构建哈希,或者对数据集进行排序和合并.这些 *** 作都是O(n * log(n))或更好.)一小部分快速查询很快.
尽管很痛苦,如果你想让这个查询更快,那么你需要像以前的查询一样将其分解出来.
总结以上是内存溢出为你收集整理的oracle – 解释计划成本与执行时间全部内容,希望文章能够帮你解决oracle – 解释计划成本与执行时间所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)