今天總結下最近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,
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語句
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'
) ;
請大家注意下上面提到的問題,謝謝!