複雜SQL優化

 

SQL:

 select *
           from (select  distinct action_Type_Name as actionName,
                                 toRZ,
                                 custName,
                                 partyTypeCd,
                                 t.ol_nbr,
                                 channelName,
                                 staffName,
                                 soDate,
                                 ct.status,
                                 ct.status as stName,
                                 t.staff_number,
                                 t.region_id,
                                 t.region_name as areaName,
                                 t.access_number,
                                 '0' as wzType,
                                 '' deal,
                                 '' checkLog,
                                 '' hzPdf,
                                 '' cut,
                                 '' olNbrLink,
                                 pdf_type,
                                 '' pdfZg,
                                 case
                                   when e.attr_value_name is null then
                                    t.SYSTEM_SOURCE
                                   else
                                    e.attr_value_name
                                 end system_source,
                                 d.source_name as sourceName,
                                 t.sd_staff as sdStaff,
                                 t.sd_staff_name as sdStaffName 
                   from YWJH.checkwz_scene t
                   left join YWJH.check_wz_zg_status ct
                     on t.ol_nbr = ct.ol_nbr
                   left join YWJH.checkwz_source d
                     on d.source_order = t.order_source
                   left join YWJH.sys_source_desc e
                     on e.attr_value = t.SYSTEM_SOURCE
                  where 1 = 1
                    AND (EXISTS (select 1
                                   from YWJH.V_CHANNEL_BSS_staff_nj sto
                                  where sto.staff_code = 'WTXF002'
                                    and sto.org_id = t.channel_id) or
                         (t.sd_staff = 'WTXF002') or
                         (t.staff_number = 'WTXF002'))
                    and ct.status in ('F', 'RF', 'WC')
                    and t.city_id = '20'
                     union
                   select distinct action_Type_Name as actionName,
                                   toRZ,
                                   custName,
                                   partyTypeCd,
                                   t.ol_nbr,
                                   channelName,
                                   staffName,
                                   soDate,
                                   ct.status,
                                   ct.status as stName,
                                   t.staff_number,
                                   t.region_id,
                                   t.region_name as areaName,
                                   t.access_number,
                                   '1' as wzType,
                                   '' deal,
                                   '' checkLog,
                                   '' hzPdf,
                                   '' cut,
                                   '' olNbrLink,
                                   pdf_type,
                                   '' pdfZg,
                                   '' system_source,
                                   '' sourceName,
                                   '' sdStaff,
                                   '' sdStaffName
                           from YWJH.checkwz_scene_wz_old t
                           left join YWJH.check_wz_zg_status ct
                             on t.ol_nbr = ct.ol_nbr
                          where 1 = 1
                            AND (EXISTS (select 1
                                           from YWJH.V_CHANNEL_BSS_staff_nj sto
                                          where sto.staff_code = 'WTXF002'
                                            and sto.org_id = t.channel_id) or
                                 (t.staff_number = 'WTXF002'))
                            and ct.status in ('F', 'RF', 'WC')
                            and t.city_id = '20'
                 ) aa
          order by aa.ol_nbr desc ;

執行計劃:

瞄了幾眼,這個SQL如果不該寫無法優化。

信不信由你,性能問題在 ID 14,20.  

改寫後的SQL:

select *
           from (select  distinct action_Type_Name as actionName,
                                 toRZ,
                                 custName,
                                 partyTypeCd,
                                 t.ol_nbr,
                                 channelName,
                                 staffName,
                                 soDate,
                                 ct.status,
                                 ct.status as stName,
                                 t.staff_number,
                                 t.region_id,
                                 t.region_name as areaName,
                                 t.access_number,
                                 '0' as wzType,
                                 '' deal,
                                 '' checkLog,
                                 '' hzPdf,
                                 '' cut,
                                 '' olNbrLink,
                                 pdf_type,
                                 '' pdfZg,
                                 case
                                   when e.attr_value_name is null then
                                    t.SYSTEM_SOURCE
                                   else
                                    e.attr_value_name
                                 end system_source,
                                 d.source_name as sourceName,
                                 t.sd_staff as sdStaff,
                                 t.sd_staff_name as sdStaffName 
                   from YWJH.checkwz_scene t
                   left join YWJH.check_wz_zg_status ct
                     on t.ol_nbr = ct.ol_nbr
                   left join YWJH.checkwz_source d
                     on d.source_order = t.order_source
                   left join YWJH.sys_source_desc e
                     on e.attr_value = t.SYSTEM_SOURCE
                    left join  YWJH.V_CHANNEL_BSS_staff_nj sto  on  sto.staff_code = 'WTXF002'   and sto.org_id = t.channel_id
                  where 1 = 1 
                   and (sto.staff_id is not null or  t.sd_staff = 'WTXF002'or t.staff_number = 'WTXF002')
                    and ct.status in ('F', 'RF', 'WC')
                    and t.city_id = '20'
                     union
                   select distinct action_Type_Name as actionName,
                                   toRZ,
                                   custName,
                                   partyTypeCd,
                                   t.ol_nbr,
                                   channelName,
                                   staffName,
                                   soDate,
                                   ct.status,
                                   ct.status as stName,
                                   t.staff_number,
                                   t.region_id,
                                   t.region_name as areaName,
                                   t.access_number,
                                   '1' as wzType,
                                   '' deal,
                                   '' checkLog,
                                   '' hzPdf,
                                   '' cut,
                                   '' olNbrLink,
                                   pdf_type,
                                   '' pdfZg,
                                   '' system_source,
                                   '' sourceName,
                                   '' sdStaff,
                                   '' sdStaffName
                           from YWJH.checkwz_scene_wz_old t
                           left join YWJH.check_wz_zg_status ct   on t.ol_nbr = ct.ol_nbr
                           left join  YWJH.V_CHANNEL_BSS_staff_nj sto  on  sto.staff_code = 'WTXF002'   and sto.org_id = t.channel_id
                          where 1 = 1 
                            and ( sto.staff_id is not null or t.staff_number = 'WTXF002')
                            and ct.status in ('F', 'RF', 'WC')
                            and t.city_id = '20'
                 ) aa
          order by aa.ol_nbr desc ;

效率對比

優化前:125S, 2分鐘左右

優化後:13S

信不信由你,該SQL優化後, 業務高峯期業務量增加近2倍,CPU壓力減少 50%左右。

補一個後記吧。

本身該SQL優化不難, 只是對該項目有里程碑意義。 本身業務量就大,業務性能提升不上來, 需要整體優化,但並不是很難,本次優化基本上一眼定位到系統瓶頸。 之前寫博客紀念了一個SQl, 也是簡單看兩眼,從1997S優化到 0.2S。那次 個例上面看意義很大,這次對整體意義更大。 從接手優化這個系統,到定位到問題,再到解決問題。幾乎是很快的。所以這次也該紀念下。

 

 

 

 

 

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