<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title></title>
    <description></description>
    <link>http://chenhj520.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>讨论一个比较复杂的查询语优化问题</title>
        <author>chenhj520</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://chenhj520.javaeye.com">chenhj520</a>&nbsp;
          链接：<a href="http://chenhj520.javaeye.com/blog/183084" style="color:red;">http://chenhj520.javaeye.com/blog/183084</a>&nbsp;
          发表时间: 2008年04月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          一条查询语句中包括有多个函数,函数的作用主要是主组合字符串.两个数据查询出来花了快一分多钟.<br /><br /><br /><pre name="code" class="sql">select distinct br.repeal_id,

                to_char(br.create_date, 'yyyy-MM-dd hh24:mi') as create_date,

                pbo.object_alias_name objectName,

                fun_get_Repeal_package(br.repeal_id) packageName,

                br.is_audit,

                fun_get_Repeal_CompanyName(br.repeal_id) companyName,

                (select user_name

                   from sm_t_user

                  where user_id = br.create_user_id) user_name,

                case br.is_group_report

                  when 2 then

                   '已修改'

                  when 1 then

                   '已导出'

                  when 0 then

                   '未导出'

                end as is_type,

                br.object_number,

                bpd.project_id,

                br.repeal_status,

                (select stu.user_name

                   from be_t_flow_log btf, sm_t_user stu

                  where btf.sub_user_id = stu.user_id

                    and br.repeal_status = btf.billstatus

                    and br.repeal_id = btf.repeal_id

                    and btf.flow_able &lt;> -1

                    and rownum = 1) ruser_name,

                br.create_user_id,

                br.is_group_report,

                case

                  when ((select count(*)

                           from be_t_flow_log btw

                          where btw.flow_able = 0

                            and btw.repeal_id = br.repeal_id

                            and btw.billstatus = 3

                            and btw.audit_status is null

                            and ((select count(*)

                                    from be_t_flow_log btlg

                                   where btlg.flow_able = -1

                                     and btlg.repeal_id = br.repeal_id) > 0)) > 0) then

                   'red'

                  else

                   ''

                end as color,

                'a' indexNo,

                br.blank_out,

                fun_get_Repeal_Reason(br.repeal_id) repeal_reason

  from be_t_repeal         br,

       be_t_repeal_package brp,

       be_t_project_detail bpd,

       pa_t_bid_package    pbp,

       pa_t_bid_object     pbo,

       be_t_providers      bp,

       be_t_repeal_package btr,

       BE_T_FLOW_LOG       BTFL

 where br.repeal_id = brp.repeal_id

   and brp.project_device_id = bpd.project_device_id

   and bpd.bid_package_id = pbp.bid_package_id

   and pbp.bid_object_id = pbo.bid_object_id

   and brp.provider_id = bp.provider_id

   and br.repeal_id = btr.repeal_id

   and br.repeal_id = btfl.repeal_id

   and btfl.flow_type = 1

   and br.project_id = 990000000000003243;</pre><br /><br />查询的两条数据结果：<br /><br />1 990000000000001741 2008-04-14 18:16 铁塔 包1  阿塔其大一互电器有限公司、安徽宏鼎互感器有限公司、安徽宏源电力铁塔制造股份合作公司、安徽宏源线路器材有限公司、安徽明都电力线缆有限公司、鞍山铁塔制造总厂、鞍山万事达电力有限公司、宝丰电缆有限公司、宝鸡铁塔厂、宝胜普睿司曼电缆有限公司、保定保菱变压器有限公司、保定电力修造厂、保定市华北电力线材制造有限公司、保定天威保变电气股份有限公司、保定天威互感器有限公司、北京ABB高压开关设备有限公司、北京北开电气股份有限公司、北京电力设备总厂、北京电研华源电力技术有限公司、北京宏达日新电机有限公司、北京华美煜力电力技术有限公司、北京潞电电气设备有限公司、北京送变电公司线路器材厂、长春聚德龙铁塔集团有限公司、长春三鼎变压器有限公司、常州东芝变压器有限公司、常州华银电线电缆有限公司、常州市武进恒通金属钢丝有限公司、成都双星变压器有限公司、重庆ABB变压器有限公司、重庆市江津电力线路构件厂、重庆顺泰铁塔制造有限公司、重庆渝能泰山电线电缆有限公司、传奇电气（沈阳）有限公司、大连电瓷有限公司、大连互感器有限公司、东莞市高能实业有限公司、恩基客（上海）商贸有限公司、菲尔普斯.道奇（烟台）电缆有限公司、福建德和铁塔设备制造有限公司、福建电建杆塔制造有限责任公司、福建南平太阳电缆股份有限公司、抚顺电瓷制造有限公司、甘肃长通电缆科技股份有限公司、甘肃诚信电线电缆有限责任公司、赣州联盛电力器材有限公司、广东新亚光电缆实业有限公司、广州华盛避雷器实业有限公司、广州市迈克林电力有限公司、广州维奥伊林变压器有限公司 超级管理员 未导出 T120007 990000000000003243 1 超级管理员 990000000000000001 0  a 1 产品型式不满足要求<br /><br />2 990000000000001761 2008-04-15 11:54 铁塔 包2、包4、包5、包6、包7、包8、包9、包10、包11、包12、包13、包14、包15、包16、包17、包18、包20、包22、包23、包24、包25、包26、包27、包28、包29、包30、包31、包33、包34、包35、包36、包37、包38、包39、包40、包41、包42、包43、包44、包45、包46、包48、包49、包50、包51、包52、包53、包54、包55、包56、包57、包58、包59、包60、包61、包62、包63、包64、包65、包66、包67、包68、包69  重庆顺泰铁塔制造有限公司 EP46 未导出 T120008 990000000000003243 1 EP46 990000000000006222 0  a 1 投标人资格条件不满足要求（缺少鉴定证书或许可证）<br /><br /> 两条数据花了61.016秒.<br /><br />问题主要在几个组合字符串的函数上.<br /><br />取审批单包名的函数.<br /><pre name="code" class="sql">
create or replace function fun_get_Repeal_package(p_repeal_id varchar)
  return varchar as
  cursor cur is
    select distinct pbp.package_name, pbp.package_order, pbp.child_order
      from be_t_repeal         br,
           be_t_repeal_package brp,
           be_t_project_detail bpd,
           pa_t_bid_package    pbp pa_t_bid_object pbo,
     where br.repeal_id = brp.repeal_id
       and brp.project_device_id = bpd.project_device_id
       and bpd.bid_package_id = pbp.bid_package_id
       and pbp.bid_object_id = pbo.bid_object_id
       and brp.provider_id = bp.provider_id
       and br.repeal_id = p_repeal_id
     order by pbp.package_order || pbp.child_order,
              pbp.child_order,
              pbp.package_name;
  v_package varchar2(1000);
begin
  v_package := '';
  for cur_repeal in cur loop
    v_package := v_package || cur_repeal.package_name || '、';
  end loop;
  v_package := substr(v_package, 1, length(v_package) - 1);
  return v_package;
end;
</pre><br /><br />　<br /><br /> 一个审批单对应的包数据比较多是,查询出来数据非常慢.<br /><br />获得审批单对应供应商函数<br /><br /><pre name="code" class="sql">create or replace function fun_get_Repeal_CompanyName(p_repeal_id varchar)

  return varchar as

  cursor cur is

    select distinct bp.company_fullname

      from be_t_repeal         br,

           be_t_repeal_package brp,

           be_t_project_detail bpd, 

           be_t_providers bp

     where br.repeal_id = brp.repeal_id

       and brp.project_device_id = bpd.project_device_id 

       and brp.provider_id = bp.provider_id

       and br.repeal_id = p_repeal_id

     order by nlssort(bp.company_fullname, 'NLS_SORT=SCHINESE_PINYIN_M');

  v_company_name varchar2(1000);

begin

  v_company_name := '';

  for cur_repeal in cur loop

    v_company_name := v_company_name || cur_repeal.company_fullname || '、';

  end loop;

  v_company_name := substr(v_company_name, 1, length(v_company_name) - 1);

  return v_company_name;

end;</pre><br /> 得到审批单废标原因函数<br /><br /><pre name="code" class="sql">create or replace function fun_get_Repeal_Reason(p_repeal_id varchar)

  return varchar as



  v_reason_conten varchar(1000);



  cursor cur is

    select distinct bt.reason_content

      from be_t_repeal_reson bt, be_t_repeal_package btrp

     where bt.repeal_reason_id = btrp.repeal_reason_id

       and btrp.repeal_id = p_repeal_id;

begin



   v_reason_conten:='';

    for cur_re in cur loop

      v_reason_conten:=v_reason_conten||cur_re.reason_content||'、';

    end loop;



     v_reason_conten := substr(v_reason_conten, 1, length(v_reason_conten) - 1);



  return   v_reason_conten;

end;





</pre><br /><br />正常情况下直接查询这几个函数非常快.<br /><br /><pre name="code" class="sql">select fun_get_repeal_companyname(990000000000001761) from dual;



select fun_get_repeal_package(990000000000001761) from dual;</pre><br /><br /> 第一条查询只花费时间0.016秒,第二条数据,花费0.015秒<br /><br /><br />当我去掉这几个函数时同形个查询语只用了0.19秒.<br /><br />能提供的点优化思路吗?谢谢各位了
          <br/>
          <span style="color:red;">
            <a href="http://chenhj520.javaeye.com/blog/183084#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 16 Apr 2008 00:09:00 +0800</pubDate>
        <link>http://chenhj520.javaeye.com/blog/183084</link>
        <guid>http://chenhj520.javaeye.com/blog/183084</guid>
      </item>
  </channel>
</rss>