小弟想写一个存储过程,需求如下
表:tb_ac001 
表中字段:TELD, TELH, TELN,TELI,HP_TELD, HP_TELH ,HP_TELN,CUST_LVL
需求:
传入一个变量ANI_Code ,用这个ANI_Code作为条件与TELD, TELH, TELN,TELI这四个拼接出来的值,或者HP_TELD, HP_TELH ,HP_TELN 这三个字段拼接出的值做比较,如果只有一条数据,那么需要找到CUST_LVL的值并作为一个变量输出,如果没有数据或者有两条以上的数据那么直接赋值变量输出。我发现我一个select count *,在数据库中就跑了5秒。。让我很无语。求各位路过的大神帮忙优化一下,小弟感激不尽。。谢谢
create or replace procedure  PD_GetCustlvl( ANI_Code  IN varchar2,DNIS_Code            OUT varchar2
  ) is
 
 i            integer;
  ai_ani_code varchar2(20);
begin
  ai_ANI_Code := substr(ANI_Code,-11,11);
  select count(*)
    into i
    from tb_ac001
   where substr(TELD || TELH || TELN || TELI,-11,11) =ai_ani_code or HP_TELD || HP_TELH|| HP_TELN = ai_ANI_Code;
   --如果有手机记录,并且只有1条
  if i = 1 then
    select decode(CUST_LVL_CD,
                  '90',
                  '10',
                  '80',
                  '20',
                  '50',
                  '30',
                  '40',
                  '40',
                  '30',
                  '50',
                  '20',
                  '80',
                  '10',
                  '90',
                  'no')
      into DNIS_Code
      from tb_ac001
     where substr(TELD || TELH || TELN || TELI,-11,11) = ai_ANI_Code or HP_TELD || HP_TELH|| HP_TELN = ai_ANI_Code;     
   
  --如果记录不只1条
  else
    if i <> 1 then
      DNIS_Code := 30;
     
    end if;
  end if;
   
  end PD_GetCustlvl; 数据库优化存储

解决方案 »

  1.   

    你先把TELD || TELH || TELN || TELI 这3个合并的先取出来!然后创建索引 在与入参关联!试下!
      

  2.   

    创建函数索引和索引,然后,再加上and rownum<=2;
      

  3.   

    Create Or Replace Procedure Pd_Getcustlvl(Ani_Code  In Varchar2,
                                              Dnis_Code Out Varchar2) Is  i           Pls_Integer;
      Ai_Ani_Code Varchar2(20);
    Begin
      Ai_Ani_Code := Substr(Ani_Code, -11, 11);
      Begin
        Select Decode(Cust_Lvl_Cd,
                      '90',
                      '10',
                      '80',
                      '20',
                      '50',
                      '30',
                      '40',
                      '40',
                      '30',
                      '50',
                      '20',
                      '80',
                      '10',
                      '90',
                      'no')
          Into Dnis_Code
          From Tb_Ac001
         Where Substr(Teld || Telh || Teln || Teli, -11, 11) = Ai_Ani_Code
       Union  
       Select Decode(Cust_Lvl_Cd,
                      '90',
                      '10',
                      '80',
                      '20',
                      '50',
                      '30',
                      '40',
                      '40',
                      '30',
                      '50',
                      '20',
                      '80',
                      '10',
                      '90',
                      'no')
          Into Dnis_Code
          From Tb_Ac001  
       Where Hp_Teld || Hp_Telh || Hp_Teln = Ai_Ani_Code;
      Exception
        When Others Then
          Dnis_Code := 30;
      End;
    End Pd_Getcustlvl;
      

  4.   

    没看到他的执行计划,不好说,感觉他这个性能出在了fts上,你这样改,可能会更差。
    另外,你这么改,结果可能就不一样了,例如:
    union的两个SQL都没结果,那报错不?不报错,那输出参数应该返回30,但没返回;如果SQL没返回结果报错的话,假如其中一个SQL返回一条记录,另一个没返回记录,本来合起来结果应该是1,结果报错了,返回了30;还有很多其他情况
      

  5.   

    试试建个substr的函数索引,另外,换成union all