oracle – 解释计划成本与执行时间

在此之前,我发现执行计划中的“成本”是相对执行时间的良好指标.为什么这种情况不同?我认为执行计划具有相关性我是个傻瓜吗?具体可以尝试提高v_test的性能

谢谢.

使用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))或更好.)一小部分快速查询很快.

尽管很痛苦,如果你想让这个查询更快,那么你需要像以前的查询一样将其分解出来.

相关文章

Java Oracle 结果集是Java语言中处理数据库查询结果的一种方...
Java AES和Oracle AES是现代加密技术中最常使用的两种AES加密...
Java是一种广泛应用的编程语言,具备可靠性、安全性、跨平台...
随着移动互联网的发展,抽奖活动成为了营销活动中不可或缺的...
Java和Oracle都是在计算机领域应用非常广泛的技术,他们经常...
Java 是一门非常流行的编程语言,它可以运行于各种操作系统上...