ORACLE 11gR2 Cardinality Feedback 的优化案例

今天一同事发邮件说,有个sql,第一次跑的很快,后面跑的很慢,要我优化下,由于没有权限,不能查看oracle的数据字典(坑爹)执行计划也看不了,于是只有从sql,方面来着手(不看执行计划也能优化?具体咨询骚落和教主),不扯淡了,来看sql。

Select *
  From (Select Distinct x.Bar_Code As Barcode,
                        x.Instance_Id As Processinstanceid,
                        x.Code As Processcode,
                        x.Priority As Priority,
                        z.Ati_Atdname As Nodename,
                        z.Wki_User As Userid,
                        To_Char(z.Wki_Createtime, 'yyyy-mm-dd hh24:mi:ss') As Arrivetime,
                        Ati_Endtime
          From (Select Distinct x.*
                  From (Select a.Bar_Code
                          From f_Loan_Info a
                         Where a.Apply_Date >=
                               to_date('2010-05-25 00:00:00',
                                            'yyyy-mm-dd hh24:mi:ss')
                           And a.Apply_Date <=
                               to_date('2015-05-25 23:59:59',
                                            'yyyy-mm-dd hh24:mi:ss')
                           And a.Apply_City = '02'
                           And a.Apply_Channal In
                               (Select Paid
                                  From Pa_Simpleness_Mode
                                 Where Patable = 'PA_SALES_CHANNAL'
                                   And Pastate = 1)
                           And (a.Follow_Branch In
                               (Select Branchcode
                                   From Pa_Branch
                                  Where Pastate = 1
                                    And BrAnchcode = '0298') Or
                               a.Audit_Branch In
                               (Select Branchcode
                                   From pa_Branch
                                  Where Pastate = 1
                                    And Branchcode = '0298') Or
                               a.Lending_Branch In
                               (Select Branchcode
                                   From Pa_Branch
                                  Where Pastate = 1 And Branchcode = '0298'))
                           And a.Apply_Loan_Product In
                               (Select DistiNct Paproductcode
                                  From Pa_Loan_Pro_c
                                 Where Pastate = 1
                                   And Pa_CoMpany_c = '02')
                        Union
                        Select b.Bar_Code
                          From f_Scan_Loan_Track b
                         Where b.Oper_Time >=
                               to_date('2010-05-25 00:00:00',
                                            'yyyy-mm-dd hh24:mi:ss')
                           And b.Oper_Time <=
                               to_date('2015-05-25 23:59:59',
                                            'yyyy-mm-dd hh24:mi:ss')
                           And b.Applicant_City = '02'
                           And b.Channal In
                               (Select Paid
                                  From Pa_Simpleness_Mode
                                 Where Patable = 'PA_SALES_CHANNAL'
                                   And Pastate = 1)
                           And b.Follow_Branch In
                               (SeLect Branchcode From Pa_Branch Where
                                Pastate = 1 And Branchcode = '0298')
                           And b.Loan_Product In
                               (Select Distinct Paproductcode FrOm Pa_Loan_Pro_c Where Pastate = 1 And Pa_Company_c = '02')
                           And Not Exists
                         (Select Bar_Code
                                  From f_Loan_Info
                                 Where Bar_Code = b.bAr_Code)
                        Union
                        Select c.Bar_Code
                          From f_App_Loan_Track c
                         Where c.Create_Date >=
                               to_date('2010-05-25 00:00:00',
                                            'yyyy-mm-dd hh24:mi:ss')
                           And c.Create_Date <=
                               to_date('2015-05-25 23:59:59',
                                            'yyyy-mm-dd hh24:mi:ss')
                           And c.Applicant_City = '02'
                           And 'KF' In (Select Paid
                                          From Pa_Simpleness_Mode
                                         Where Patable = 'PA_SALES_CHANNAL'
                                           And Pastate = 1)
                           And c.Follow_Branch In
                               (Select BrancHcode
                                  From Pa_Branch
                                 Where Pastate = 1
                                   And Branchcode = '0298')
                           And c.Loan_Product In
                               (Select Distinct Paproductcode
                                  From Pa_Loan_Pro_c
                                 Where Pastate = 1
                                   And Pa_Company_c = '02')
                           And Not Exists
                         (Select Bar_Code
                                  From f_Loan_Info
                                 Where Bar_Code = c.Bar_Code)) t,
                       Uaf_Flow_Track x
                 Where t.Bar_Code = x.Bar_Code
                   And x.Loanstate = 'RJ') x
          Left Join (Select a.Ati_Priid,
                           a.Ati_Atdname,
                           b.Wki_User,
                           b.Wki_Createtime,
                           a.Ati_Endtime
                      From Sunflow.Actiinstance a LeFt
                      Join Sunflow.Workitem b
                        On a.Ati_Priid = b.Wki_Priid
                       And a.Ati_Id = b.Wki_Atiid
                     Where a.Ati_Id In
                           (Select Max(Ati_Id)
                              From SunFlow.Actiinstance
                             Where Ati_Priid = a.Ati_Priid)) z
            On x.Instance_Id = z.Ati_Priid)
 Order By Barcode Desc

这个sql总体来看,并不复杂,就是x表和z表关联,由于不能看执行计划,就把x表和z表单独拿出来跑一下,发现z表跑的有点慢,于是就把以前的sql改写成下面这样了。

Select  *
  From (Select Distinct x.Bar_Code As Barcode,
                        x.Instance_Id As Processinstanceid,
                        x.Code As Processcode,
                        x.Priority As Priority,
                        z.Ati_Atdname As Nodename,
                        z.Wki_User As Userid,
                        To_Char(z.Wki_Createtime, 'yyyy-mm-dd hh24:mi:ss') As Arrivetime,
                        Ati_Endtime
          From (Select Distinct x.*
                  From (Select a.Bar_Code
                          From f_Loan_Info a
                         Where a.Apply_Date >=
                               To_Date('2010-05-25 00:00:00',
                                       'yyyy-mm-dd hh24:mi:ss')
                           And a.Apply_Date <=
                               To_Date('2015-05-25 23:59:59',
                                       'yyyy-mm-dd hh24:mi:ss')
                           And a.Apply_City = '02'
                           And a.Apply_Channal In
                               (Select Paid
                                  From Pa_Simpleness_Mode
                                 Where Patable = 'PA_SALES_CHANNAL'
                                   And Pastate = 1)
                           And (a.Follow_Branch In
                               (Select Branchcode
                                   From Pa_Branch
                                  Where Pastate = 1
                                    And Branchcode = '0298') Or
                               a.Audit_Branch In
                               (Select Branchcode
                                   From Pa_Branch
                                  Where Pastate = 1
                                    And Branchcode = '0298') Or
                               a.Lending_Branch In
                               (Select Branchcode
                                   From Pa_Branch
                                  Where Pastate = 1
                                    And Branchcode = '0298'))
                           And a.Apply_Loan_Product In
                               (Select Distinct Paproductcode
                                  From Pa_Loan_Pro_c
                                 Where Pastate = 1
                                   And Pa_Company_c = '02')
                        Union
                        Select b.Bar_Code
                          From f_Scan_Loan_Track b
                         Where b.Oper_Time >=
                               To_Date('2010-05-25 00:00:00',
                                       'yyyy-mm-dd hh24:mi:ss')
                           And b.Oper_Time <=
                               To_Date('2015-05-25 23:59:59',
                                       'yyyy-mm-dd hh24:mi:ss')
                           And b.Applicant_City = '02'
                           And b.Channal In
                               (Select Paid
                                  From Pa_Simpleness_Mode
                                 Where Patable = 'PA_SALES_CHANNAL'
                                   And Pastate = 1)
                           And b.Follow_Branch In
                               (Select Branchcode
                                  From Pa_Branch
                                 Where Pastate = 1
                                   And Branchcode = '0298')
                           And b.Loan_Product In
                               (Select Distinct Paproductcode
                                  From Pa_Loan_Pro_c
                                 Where Pastate = 1
                                   And Pa_Company_c = '02')
                           And Not Exists
                         (Select Bar_Code
                                  From f_Loan_Info
                                 Where Bar_Code = b.Bar_Code)
                        Union
                        Select c.Bar_Code
                          From f_App_Loan_Track c
                         Where c.Create_Date >=
                               To_Date('2010-05-25 00:00:00',
                                       'yyyy-mm-dd hh24:mi:ss')
                           And c.Create_Date <=
                               To_Date('2015-05-25 23:59:59',
                                       'yyyy-mm-dd hh24:mi:ss')
                           And c.Applicant_City = '02'
                           And 'KF' In (Select Paid
                                          From Pa_Simpleness_Mode
                                         Where Patable = 'PA_SALES_CHANNAL'
                                           And Pastate = 1)
                           And c.Follow_Branch In
                               (Select Branchcode
                                  From Pa_Branch
                                 Where Pastate = 1
                                   And Branchcode = '0298')
                           And c.Loan_Product In
                               (Select Distinct Paproductcode
                                  From Pa_Loan_Pro_c
                                 Where Pastate = 1
                                   And Pa_Company_c = '02')
                           And Not Exists
                         (Select Bar_Code
                                  From f_Loan_Info
                                 Where Bar_Code = c.Bar_Code)) t,
                       Uaf_Flow_Track x
                 Where t.Bar_Code = x.Bar_Code
                   And x.Loanstate = 'RJ') x
          Left Join (Select Ati_Priid,
                           Ati_Atdname,
                           Wki_User,
                           Wki_Createtime,
                           Ati_Endtime
                      From (Select a.Ati_Priid,
                                   a.Ati_Atdname,
                                   b.Wki_User,
                                   b.Wki_Createtime,
                                   a.Ati_Endtime,
                                   Row_Number() Over(Partition By Ati_Priid Order By Ati_Id Desc) Rn
                              From Sunflow.Actiinstance a
                              Left Join Sunflow.Workitem b
                                On a.Ati_Priid = b.Wki_Priid
                               And a.Ati_Id = b.Wki_Atiid)
                     Where Rn = 1) z
            On x.Instance_Id = z.Ati_Priid)
 Order By Barcode Desc

这个sql拿到库里面跑,每次都是不到1s,没有出现以前的问题,那么问题算是解决了。

由于本着研究的精神,为什么第一个sql,会出现第一次跑很快,后面跑的很慢,经过研究发现是oracle11gR2新特效feedback的bug(8521689)

Cardinality Feedback

Cardinality Feedback基数反馈是版本11.2(11.2.0.1及以后)中引入的关于SQL 性能优化的新特性,该特性主要针对 统计信息陈旧、无直方图或虽然有直方图但仍基数计算不准确的情况,Cardinality基数的计算直接影响到后续的JOIN COST等重要的成本计算评估,造成CBO选择不当的执行计划。以上是Cardinality Feedback特性引入的初衷。

发生情景:

在普通用户下,在sys用户下是会发生feedback特性
1,没有收集表的统计信息,并且dynamic samping也没有开启
2,查询条件复杂(比如条件有函数)或者涉及多列,但是没有收集扩展统计信息(extend statics)

运行方式:

  1. 针对上述情况,Oracle会监控操作的实际行数(A-Row),然后对比CBO估算的行数(E-Row)。
  2. 如果两个值相差很大,就记录实际行数(A-Row),做上标记。下次执行时再次进行硬解析,根据实际行数来重新生成执行计划。
  3. 如果两个值相差不大,CBO就不再监控这条SQL语句。

使用的标志;

统计信息中有:

Note

  • cardinality feedback used for this statement

禁用feedback的方式:

hint : opt_param(‘_optimizer_use_feedback’ ‘false’)
修改参数: alter system set “_optimizer_use_feedback”=false scope=both;

hint:cardinality(test, 1)强制使用

查看share pool中还有那些sql用到了feedback

select sql_ID,USE_FEEDBACK_STATS FROM V$SQL_SHARED_CURSOR where USE_FEEDBACK_STATS =’Y’;

你可能感兴趣的:(sql,trunning)