SQLServer效能最佳化之活用暫存資料表

來源:互聯網
上載者:User

繼續調優,今天上午分析了以下一條處理時間達40秒的SQL語句
select *
  from table
 where T_table_ID in 
  (
   select  distinct s.t_table_id
     from
     ( 
      select distinct a.t_table_id,a.bt
        from  
        (select left(bt,4) as bbt,* from table where fsrq>getdate()-1 and gkbz=1 and scbz=0) a, 
        (select distinct left(bt,4) as bbt,t_table_id from table where fsrq>getdate()-1 and gkbz=1 and scbz=0) b 
       where b.bbt like a.bbt and a.t_table_id<>b.t_table_id 
         and a.bbt not like '%aaaa%' and a.bbt not like '%bbbb%' and a.bbt not like '%cccc%'
         and a.bbt not like '%dddd%' and a.bbt not like '%eeee%' and a.bbt not like '%ffff%'
         and a.bbt not like '%aaaa%' and a.bbt not like '%bbbb%' and a.bbt not like '%cccc%'
         and a.bbt not like '%dddd%' and a.bbt not like '%eeee%' and a.bbt not like '%ffff%'
         -- order by a.bt 
      union all 
      select distinct a.t_table_id,a.bt
        from  
        (select right(bt,5) as bbt,* from table where fsrq>getdate()-1 and gkbz=1 and scbz=0) a, 
        (select distinct right(bt,5) as bbt,t_table_id from table where fsrq>getdate()-1 and gkbz=1 and scbz=0) b 
       where b.bbt like a.bbt and a.t_table_id<>b.t_table_id  
         and a.bbt not like '%aaaa%' and a.bbt not like '%bbbb%' and a.bbt not like '%cccc%'
         and a.bbt not like '%dddd%' and a.bbt not like '%eeee%' and a.bbt not like '%ffff%'
         and a.bbt not like '%aaaa%' and a.bbt not like '%bbbb%' and a.bbt not like '%cccc%'
         and a.bbt not like '%dddd%' and a.bbt not like '%eeee%' and a.bbt not like '%ffff%'
         and a.bbt not like '%'+(select right(convert(varchar(10),getdate()-1,20),2)+')') +'%' 
         and b.bbt not like '%'+(select right(convert(varchar(10),getdate()-1,20),2)+')') +'%' 
       ) s  
   )order by bt 
基本上可以認為是對同一張表的反覆操作,而且語句中夾雜了太多的全表掃描
SQLServer的執行計畫我個人認為圖形化介面固然是好,但是有些時候對於量化的I/O,CPU,COST輸出卻很不直觀,此外像該SQL這樣的執行計畫,估計1600*1200的整個螢幕都無法顯示,可以認為基本是沒法看的

只能將SQL分解成若干小SQL,逐步找到瓶頸所在,例如
select left(bt,4) as bbt,* from table where fsrq>getdate()-1 and gkbz=1 and scbz=0
select distinct left(bt,4) as bbt,t_table_id from table where fsrq>getdate()-1 and gkbz=1 and scbz=0
這兩個語句的執行都非常快,並且結果集也比較小,但是兩條語句合并後並加上相關條件就非常緩慢。
乾脆直接構建兩個暫存資料表,反正都是全表掃描,用兩個暫存資料表做相互的join,測試之後發現只需要1秒
再構建下面的兩個SQL暫存資料表,也做同樣的測試
最後再全部合并到一起進行測試,發現也就是2~3秒
實際上還可以再最佳化一些暫存資料表的構建,但效果達到了也就不願意嘗試了

也嘗試過用CTE,不過似乎效果不佳
以下為最佳化後的SQL範例
/*
with temp1 as
(select left(bt,4) as bbt,* from table where fsrq>getdate()-1 and gkbz=1 and scbz=0),
temp2 as
(select distinct left(bt,4) as bbt,t_table_id from table where fsrq>getdate()-1 and gkbz=1 and scbz=0),
temp3 as
(select left(bt,5) as bbt,* from table where fsrq>getdate()-1 and gkbz=1 and scbz=0),
temp4 as
(select distinct left(bt,5) as bbt,t_table_id from table where fsrq>getdate()-1 and gkbz=1 and scbz=0)
*/
print convert(varchar,getdate(),9)
select left(bt,4) as bbt,* into #temp1 from table where fsrq>getdate()-1 and gkbz=1 and scbz=0
select distinct left(bt,4) as bbt,t_table_id into #temp2 from table where fsrq>getdate()-1 and gkbz=1 and scbz=0
select right(bt,5) as bbt,* into #temp3 from table where fsrq>getdate()-1 and gkbz=1 and scbz=0
select distinct right(bt,5) as bbt,t_table_id into #temp4 from table where fsrq>getdate()-1 and gkbz=1 and scbz=0
select
(select ms from xtclb where dm=lmxz and lb in (130,131) ) as '欄目選擇',
 bt,mtly,czy
  from table
 where T_table_ID in 
  (
   select  distinct s.t_table_id
     from
     ( 
      select distinct a.t_table_id,a.bt
        from  
        #temp1 a, 
        #temp2 b 
       where b.bbt like a.bbt and a.t_table_id<>b.t_table_id 
         and a.bbt not in ('aaaa','bbbb','cccc','dddd','eeee','ffff')
         and b.bbt not in ('aaaa','bbbb','cccc','dddd','eeee','ffff')
      union all 
      select distinct a.t_table_id,a.bt
        from  
        #temp3 a, 
        #temp4 b 
       where b.bbt like a.bbt and a.t_table_id<>b.t_table_id  
         and a.bbt not like '%aaaa%' and a.bbt not like '%bbbb%' and a.bbt not like '%cccc%'
         and a.bbt not like '%dddd%' and a.bbt not like '%eeee%' and a.bbt not like '%ffff%'
         and a.bbt not like '%'+(select right(convert(varchar(10),getdate()-1,20),2)+')') +'%' 
         and a.bbt not like '%aaaa%' and a.bbt not like '%bbbb%' and a.bbt not like '%cccc%'
         and a.bbt not like '%dddd%' and a.bbt not like '%eeee%' and a.bbt not like '%ffff%'
         and b.bbt not like '%'+(select right(convert(varchar(10),getdate()-1,20),2)+')') +'%' 
       ) s  
   )order by bt 
   --OPTION (loop join);
   --34
print convert(varchar,getdate(),9)  
/*
drop table #temp1  
drop table #temp2
drop table #temp3
drop table #temp4
*/

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.