SQL調優--記一次表統計信息未及時更新導致查詢超級慢


             某日同事丟給我一個看上去復雜的查詢(實際就涉及兩張表,套來套去)說只是換了日期條件,但一個查詢5秒出數據,一個根本查不出來。現在整理下解決過程,及涉及的知識點。  

  若有不正之處,請多多諒解並歡迎批評指正,不甚感激。

  請尊重作者勞動成果,轉載請標明原文鏈接:

  http://www.cnblogs.com/zzry/p/5857751.html

 

一.問題描述


環境:sqlserver 2008r2 

現象:

查詢涉及到兩張表

ODS_TABLE_A     每日數據700萬現在總計60多億。   已建立索引+分區

MID_TABLE_B      每日數據20萬 總計3000萬。         已建立索引未分區

當etldate為 '2016-08-12' 及以前的時間時,本查詢5秒出數據,

當etldate為 '2016-08-16' 及以后的時間時,本查詢出不來數據。

貼上問題sql:做過數據字段處理,針對本篇主題注意點放在查詢因為日期的選擇不同導致查詢時間變的超級慢,而不是改變sql寫法比如用臨時表,強制索引上。

 

----------《代碼開始》

select 

COUNT(distinct(case when COL_USERID3 is null then COL_USERID6 end)) as 'aa',

COUNT(distinct(case when COL_USERID3 is null and COL_USERID7 is not null then COL_USERID6 end)) as 'bb',

COUNT(distinct(case when COL_USERID3 is not null then COL_USERID6 end)) as 'cc',

COUNT(distinct(case when COL_USERID3 is not null and COL_USERID7 is not null then COL_USERID6 end)) as 'dd',

SUM(case when COL_USERID3 IS not null then ee end) as 'ee'

from

(

    select c.COL_USERID3,c.ee,g.COL_USERID6

    from

    (

        select  b.COL_USERID2 as COL_USERID3,COUNT(b.COL_USERID2) as ee

        from

        (

            select COL_USERID as COL_USERID1,min(EventTime) as time1

                from ODS_TABLE_A    

                where  EtlDate = '2016-08-12'

                    and colid LIKE 'heihei%'

                    group by COL_USERID
 
        )as a
         join
        (
            select COL_USERID as COL_USERID2,eventtime as time2

                from ODS_TABLE_A  

                where EtlDate = '2016-08-12'

                    and ItemId = '1111111111101'

                    and colid like 'haha-%'

                    and colid not like 'haha-skill%'

                    and colid not like 'haha-fine%'

        )as b 

        on a.COL_USERID1 = b.COL_USERID2 and  a.time1 > b.time2

        group by b.COL_USERID2

    )as c
    right join
    (

        select  DISTINCT d.COL_USERID4 as COL_USERID6

        from

        (        
            select distinct COL_USERID as COL_USERID4

            from MID_TABLE_B     

            where etldate = '2016-08-12' 

        )as d

        join

        (
            select COL_USERID AS COL_USERID5

            from ODS_TABLE_A  

            where  EtlDate = '2016-08-12'

                and colid LIKE 'heihei%'

        )as f 

        on d.COL_USERID4 = f.COL_USERID5

    )as g

    on c.COL_USERID3 = g.COL_USERID6

)as i

left join
(
    select COL_USERID as COL_USERID7

    from MID_TABLE_B

    where EtlDate = '2016-08-12' 

        and IsTodayPay = '1'

)as h

on i.COL_USERID6 = h.COL_USERID7

 ----------《代碼結束》

 

二。解決過程


 1.先看了下上述代碼的執行計划如下圖初看上去需要用索引的地方都用到了。應該沒啥大問題。

可能你注意到系統提示的缺少索引信息,加上去一樣效果,不能解決‘2016-08-16’ 查詢慢的問題。

 

 

 

 2.在修改下日期 ,就是把  所有】   etldate=‘2016-08-12’  的改成    etldate=‘2016-08-16’
看下執行計划:
對不起跑了半個小時沒出來,查看估計的執行執行和上面的圖類似。
減少涉及到數據集的量 加top 1 我再看執行計划:
不貼圖了 結果就是比上面的圖少了個 【並行度
 
初步以為是優化器因為估計行數等不准的原因沒選擇並行度,趕緊找代碼讓它強行這樣走。
找到一篇宋大師的:強制SQL Server執行計划使用並行提升在復雜查詢語句下的性能
http://www.cnblogs.com/CareySon/p/3851113.html
 
 二話不說加關鍵字
OPTION(querytraceon 8649)
 
可是應用到實際發現查詢效率無任何改善,久久不出結果。后來問宋大師(感謝宋大神)。他說有些操作是沒法並行的,更新統計信息試試先。
一擊命中! 一擊命中! 一擊命中!
執行如下代碼:
update STATISTICS ODS_TABLE_A  --(把ODS_TABLE_A  這個大表統計信息更新)
 
默認情況下,查詢優化器已根據需要更新統計信息以改進查詢計划;但在某些情況下,你可以通過使用 UPDATE STATISTICS 或存儲過程 sp_updatestats 來比默認更新更頻繁地更新統計信息,提高查詢性能。針對文中此種情況 新插入的數據沒統計信息,大表自動更新統計信息觸發自動更新機制頻率不夠,最好定期更新。
關於 update STATISTICS 就不累述了 : 給出相關技術貼連接
更新統計相關知識點傳送門https://msdn.microsoft.com/zh-cn/library/ms187348.aspx
至此問題解決。

 

三。總結


  對於大表新插入的數據沒及時更新統計信息,導致出現上面文中的現象,一個日期導致查詢效率天壤之別的分水嶺(查12號前5秒出數據,查12號后死活不出來。) 

    解決辦法是大表自動更新統計信息觸發自動更新機制頻率不夠,定期更新。

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM