已将以下代码添加到我的SQL查询中:(注意减少版本)
DECLARE @rowType AS TABLE (
rowTypeLabel NVARCHAR (20));
INSERT INTO @rowType
VALUES ('Cumulative');
INSERT INTO @rowType
VALUES ('Non-Cumulative');
--select * from @rowType
SELECT ID,Name,StartDate,
EndDate,
rowTypeLabel AS Period
FROM dbo.sicky CROSS JOIN @rowType
WHERE (rowTypeLabel = 'Cumulative'
OR (rowTypeLabel = 'Non-Cumulative'
AND (EndDate IS NULL
OR EndDate BETWEEN CAST (DateAdd(Day, 1 - Day(getDate()), getdate()) AS DATE) AND CAST (DateAdd(month, 1, DateAdd(Day, -Day(getDate()), getdate())) AS DATE))));
运行时间已经从大约10分钟变为大约1小时,有没有人有任何关于为什么会这样的建议,没有这个交叉连接的结果大约是46,000,之后再带回231行(任何分类根据查询为“非累积”。
答案 0 :(得分:4)
我猜这是一个非常简单的例子?所以我不能给你具体细节,但简单的答案是查询的累积部分比非累积部分做了更多的工作。
尝试这两个进行比较......
SELECT ID,Name,StartDate,
EndDate,
rowTypeLabel AS Period
FROM dbo.sicky
和...
SELECT ID,Name,StartDate,
EndDate,
rowTypeLabel AS Period
FROM dbo.sicky
WHERE EndDate IS NULL
OR EndDate BETWEEN CAST (DateAdd(Day, 1 - Day(getDate()), getdate()) AS DATE) AND CAST (DateAdd(month, 1, DateAdd(Day, -Day(getDate()), getdate())) AS DATE))));
后者,我预计,将需要更长的时间。
此外,合并多个业务逻辑的OR
条件对于优化器来说可能非常困难。这意味着以下结构可能更有效......
SELECT * FROM <non cumulative query>
UNION ALL
SELECT * FROM <cumulative query>
答案 1 :(得分:1)
我不明白为什么你需要这里的CROSS JOIN结构 - 这只是让问题混乱。我会重写查询:
SELECT ID, Name, StartDate, EndDate, 'Cumulative' AS Period
FROM dbo.sicky
UNION ALL
SELECT ID, Name, StartDate, EndDate, 'Non-Cumulative' AS Period
FROM dbo.sicky
WHERE EndDate IS NULL
OR EndDate BETWEEN CAST (DateAdd(Day, 1 - Day(getDate()), getdate()) AS DATE) AND CAST (DateAdd(month, 1, DateAdd(Day, -Day(getDate()), getdate())) AS DATE))));
此应等同,但会更清楚地说明您正在做的事情。假设这个UNION的第一部分是你之前的,而第二部分是慢的,那么EndDate(或你的实际查询中的等价物)可能没有被正确编入索引并且导致过度扫描。发布您的执行计划以进行更详细的分析。
答案 2 :(得分:0)
对于没有JOIN或子查询的简单SELECT,10分钟内有46000行......看起来太多了。检查您是否在StartDate和EndDate上创建并启用了索引。如果是这样的话,我会与mwigdahl o Dems回答。