oracle (二)

今天總結下最近SQL REVIEW時遇見的常見問題,下面是同事發我的SQL,比較有代表性,就一一說下存在的問題。

 

selectcount(*)

  from (

       

        select t.title as title,

               t.consume as price,

               t.address as address,

               t.spic as pic,

               t.huodongoutline as descp,

                cast(t.createdateas date) as publishDate,

               t.topindex as topIndex,

               t.type astype,

               t.work_number asid,

               t.pa_pash_youhui_id as id1,

               t.WORK_NUMBER as WORK_NUMBER,

               t.showenrollbtn as showEnrollBtn,

               t.showpaybtn as showPayBtn

          frompa_pash_youhui_info t

         where t.city in ('上海', '全國')

          AND t.TYPE = '0'

          and trunc(t.dateStart) <= trunc(sysdate)

          and trunc(t.dateEnd) >= trunc(sysdate)

          AND ((t.topIndex = '999'or (t.topIndex in ('1', '2', '3') and

              t.topTime < trunc(sysdate))))

       

        )cms_expand,

       coupon_count c

wherec.huodong_type(+) = 1

   and cms_expand.WORK_NUMBER= c.WORK_NUMBER(+) ;

 

說一下存在的問題

1,  爲了做一個count(*)的操作,在子查詢中select 出了不必要的字段(除了WORK_NUMBER字段外連接用到了之外其它全是多餘的),而且還對一個字段使用了不必要的函數(cast(t.createdate as date) as publishDate)操作;

 

2,  Where 條件中對錶字段使用了多餘的函數;

 

3,  做count(*)操作一般不會用到外連接。因爲外連接是要把一個表相應的結果集做全部的展示,另一個表不匹配的使用null代替,這種情況完全可以對單個表做count(*)操作,如果要用到另外一個表可以同時使用exists 操作,而不是使用連接,如果連接的字段不是主鍵也有可能產生笛卡爾積,導致count(*)的結果不正確。最終確認這裏的連接是不需要的,coupon_count表也是多餘的。

 

所以最終改寫成了下面的sql語句

 

SELECTCOUNT(*)

FROM  pa_pash_youhui_info t

WHERE  t.city IN ('上海', '全國')

AND   t.type = '0'

AND   t.datestart <= trunc(SYSDATE)

AND   t.dateend >= trunc(SYSDATE)

AND   (t.topindex = '999'OR

      (t.topindex IN ('1', '2', '3') AND t.toptime <trunc(SYSDATE)));

 

下面是前兩天生產庫報異常的sql,也是類似的問題

 

selectcount(m.resource_id)

  from (selectdistinct v.*

         from (

 

         selectmax(t.resource_id) asresource_id,

                      max(decode(e1.expand_key, 'startDate',e1.expand_value)) as stardateValue,

                      max(decode(e1.expand_key, 'endDate',e1.expand_value)) as enddateValue,

                      max(decode(e1.expand_key, 'qixiang',e1.expand_value)) as qixiangValue,

                      max(decode(e1.expand_key,

                                 'fengxiandengji',

                                 e1.expand_value)) as fengxiandengjiVAlue

                 from (select p.resource_id, p.resource_link

                         from cms_online_resource_props p   

                         where p.resource_type = '5110'

                          and p.resource_path like

                              '/sites/bank.pingan.com/licaichanpin/%.shtml') t

                 join cms_online_resource_expand e1 one1.resource_id =

                                                       t.resource_id

                groupby e1.resource_id

                

                 

                 )v

         leftjoin cms_online_resource_expand m1 on m1.resource_id =

                                                    v.resource_id

        where m1.expand_key = 'yuqishouyiquery') m

where1 = 1 ;

 

可以等價改成下面的sql(初步分析與測試是等價的):

 

selectcount(*)

   fromcms_online_resource_props p

  wherep.resource_type = '5110'

  andp.resource_path like'/sites/bank.pingan.com/licaichanpin/%.shtml'

  andexists (select0

     from cms_online_resource_expand m

    where m.resource_id = p.resource_id

    and m.expand_key = 'yuqishouyiquery'

   ) ;

 

 

請大家注意下上面提到的問題,謝謝!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章