2015-10-13 107 views
0

我想從一個很好的大小(18,243,847行)的表中總結橫幅廣告視圖。我需要在過去兩年中收集意見。我試着給日期添加一個索引,並嘗試下面查詢的不同變體。大多數運行時間大約是25秒,但是當它在Web服務中傳遞時,目標頁面超時。我知道問題與計數有關,但無法將該部分降至11秒以下。似乎不是很多,但爲什麼我的網絡服務的問題?無論如何,首先要做的是,這個查詢是否能夠做到最好?優化緩慢運行計數查詢

SELECT ba.adID, ba.name, ba.description, ba.startDate, ba.endDate, isNull(v.viewCount,0) AS viewCount, isNull(c.clickCount,0) AS clickCount 
FROM bannerAds ba 
    LEFT OUTER JOIN (SELECT adID, count(viewID) AS viewCount 
        FROM bannerAdsViews 
        WHERE viewDateTime IS NOT NULL AND viewDateTime >= DateAdd(yy, -2, GetDate()) 
        GROUP BY adID) v ON ba.adID = v.adID 
    LEFT OUTER JOIN (SELECT adID, count(viewID) AS clickCount 
        FROM bannerAdsViews 
        WHERE clickDateTime IS NOT NULL AND viewDateTime >= DateAdd(yy, -2, GetDate()) 
        GROUP BY adID) c ON ba.adID = c.adID 
WHERE viewCount > 0 
ORDER BY name ASC 
FOR XML RAW ('Banner'), ROOT ('Banners'); 
+0

不是每個人都回答的問題,但爲什麼不爲每個橫幅創建數據的每日總結視圖,然後查詢。因此,如果您隨後將此更新作爲計劃作業,觸發器或記錄這些統計信息的一部分的一部分,而不是遍歷1800萬條記錄,則只需查看幾百條記錄(取決於您的日期範圍)每次要運行此查詢時都必須繼續完成計算。 –

+1

爲了優化查詢,我首先運行語句解釋,否則只會優化錯誤的部分。 – AlexN

回答

2

此查詢可能很難獲得真正的良好性能。你正在總結很多數據。

但是,不需要兩個子查詢。如果我做的假設viewIDviewDateTime都在相同的記錄都NULL,那麼我覺得這個版本相當於:

SELECT ba.adID, ba.name, ba.description, ba.startDate, ba.endDate, 
     COALESCE(vc.viewCount, 0) as viewCount, 
     COALESCE(vc.clickCount, 0) as clickCount 
FROM bannerAds ba JOIN 
    (SELECT adID, count(viewDateTime) as viewCount, 
      count(clickDateTime) as clickCount 
     FROM bannerAdsViews 
     WHERE viewDateTime >= DateAdd(year, -2, GetDate())    
     GROUP BY adID 
    ) vc 
    ON ba.adID = v.adID 
WHERE viewCount > 0 
ORDER BY name ASC 
FOR XML RAW ('Banner'), ROOT ('Banners'); 

INNER JOIN可以代替LEFT JOIN,因爲WHERE子句反正去除NULL值。

+0

看起來不錯,把它降到10秒。我沒有考慮將這兩個統計結合成一個查詢,這似乎很有意義。 COALESCE是更快還是隻是首選還是無效? –

+0

看起來'ISNULL'有點快。見http://stackoverflow.com/questions/2287642/which-is-quicker-coalesce-or-isnull和http://dba.stackexchange.com/questions/4274/performance-difference-for-coalesce-versus-isnull 。 – ForguesR

+0

@ConnieDeCinko。 。 。我更喜歡'coalesce()',因爲它是ANSI標準並接受兩個以上的參數。 SQL Server對'isnull()'有更好的實現(因爲第一個參數不被計算兩次)。對於只讀取列,差異可以忽略不計。當第一個參數很昂貴時,比如函數all或子查詢,由於性能原因,'isnull()'肯定是首選。 –