我正在尝试从一个非常好的大小(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 :(得分:2)
这个查询很难获得真正好的表现。您正在总结大量数据。
但是,不需要两个子查询。如果我假设viewID
和viewDateTime
在同一记录上都是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
值。