我有一个查询,大约需要11秒才能运行一个日期。我希望运行相同的查询多天。换句话说,我希望能够返回多天的快照。这是我原来的疑问:
SELECT
COUNT(*) AS 'Number of Cars',
d.ManufacturerName AS 'Make',
d.Name AS 'Model',
c.name AS 'Car Class'
FROM CarRating a
INNER JOIN OwnedCar b ON a.OwnedCarID = b.OwnedCarID
INNER JOIN CarClass c ON a.CarClassID = c.CarClassID
INNER JOIN BaseCar d ON b.BaseCarID = d.BaseCarID
WHERE
@myDate < a.ExpiredWhen AND @myDate >= a.EffectiveWhen
GROUP BY
d.Name, c.name,d.ManufacturerName
就像我提到的查询需要11秒。为了对多个日期运行此查询,我使用日期表并将其交叉应用于上述查询:
SELECT [DATE], b.* FROM DimDate
CROSS APPLY
(SELECT
COUNT(*) AS 'Number of Cars',
d.ManufacturerName AS 'Make',
d.Name AS 'Model',
c.name AS 'Car Class'
FROM CarRating a
INNER JOIN OwnedCar b ON a.OwnedCarID = b.OwnedCarID
INNER JOIN CarClass c ON a.CarClassID = c.CarClassID
INNER JOIN BaseCar d ON b.BaseCarID = d.BaseCarID
WHERE
dimDate.Date < a.ExpiredWhen AND dimDate.Date >= a.EffectiveWhen
GROUP BY
d.Name, c.name,d.ManufacturerName) b
WHERE DimDate.Date between @StartDate and @EndDate
即使是一天,此查询也需要49秒。为什么这么慢?有没有更好的方法呢?
答案 0 :(得分:1)
您的查询速度较慢,因为它正在加入维度表,从而大大增加了正在处理的数据量。您可以通过确保具有适当的索引来修复此查询:
如果这没有帮助,那么您需要重新考虑查询。有一种替代方法可以编写它,但索引可以更简单地解决问题。
答案 1 :(得分:0)
我自己并不熟悉CROSS APPLY
,但你不能只按照范围添加ExpiredWhen
和分组,如下所示:
SELECT
a.ExpiredWhen AS dimDate
, COUNT(*) AS 'Number of Cars'
, d.ManufacturerName AS 'Make'
, d.Name AS 'Model'
, c.name AS 'Car Class'
FROM CarRating a
INNER JOIN OwnedCar b ON a.OwnedCarID = b.OwnedCarID
INNER JOIN CarClass c ON a.CarClassID = c.CarClassID
INNER JOIN BaseCar d ON b.BaseCarID = d.BaseCarID
WHERE a.ExpiredWhen between @StartDate AND @EndDate
GROUP BY
a.ExpiredWhen, d.Name, c.name, d.ManufacturerName
答案 2 :(得分:0)
您可以尝试按以下方式修改查询,然后分享结果(如果您观察到任何改进)
SELECT [DATE], b.* FROM DimDate
CROSS APPLY
(SELECT
**COUNT(1)** AS 'Number of Cars',
d.ManufacturerName AS 'Make',
d.Name AS 'Model',
c.name AS 'Car Class'
FROM CarRating a
INNER JOIN OwnedCar b ON a.OwnedCarID = b.OwnedCarID
**AND dimDate.Date < a.ExpiredWhen AND dimDate.Date >= a.EffectiveWhen**
INNER JOIN CarClass c ON a.CarClassID = c.CarClassID
INNER JOIN BaseCar d ON b.BaseCarID = d.BaseCarID
GROUP BY
d.Name, c.name,d.ManufacturerName) b
WHERE DimDate.Date between @StartDate and @EndDate
答案 3 :(得分:0)
它真的需要是交叉应用/子查询吗?看起来它正以这种方式做更多的工作。难道不能留下加入吗?
SELECT
dimDate.[Date]
COUNT(1) AS 'Number of Cars',
d.ManufacturerName AS 'Make',
d.Name AS 'Model',
c.name AS 'Car Class'
FROM DimDate
LEFT OUTER JOIN CarRating a ON dimDate.[Date] < a.ExpiredWhen AND dimDate.[Date] >= a.EffectiveWhen
LEFT OUTER JOIN OwnedCar b ON a.OwnedCarID = b.OwnedCarID
LEFT OUTER JOIN CarClass c ON a.CarClassID = c.CarClassID
LEFT OUTER JOIN BaseCar d ON b.BaseCarID = d.BaseCarID
GROUP BY dimDate.[Date], d.Name, c.name,d.ManufacturerName
答案 4 :(得分:0)
当在医疗数据集中的大型表上使用时,我在MS SQL服务器中与CROSS APPLY有类似的经历。我在谈论添加CROSS APPLY时执行时间增加了几个数量级。
经过一番探索后,我发现使用PIVOT非常有效,从&gt;开始查询18小时到2分钟(!)所以我想我会分享这个2c小费。乔。