优化慢速运行计数查询

时间:2015-10-13 15:53:29

标签: sql sql-server sql-server-2008

我正在尝试从一个非常好的大小(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');

1 个答案:

答案 0 :(得分: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值。