1

已将以下代码添加到我的 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 行(任何被归类为“非-cumulative' 根据查询。

4

3 回答 3

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>
于 2012-01-23T15:06:29.527 回答
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 (或您的实际查询中的任何等价物)很可能没​​有正确索引并导致过度扫描。发布您的执行计划以进行更详细的分析。

于 2012-01-23T15:10:06.057 回答
0

一个没有 JOIN 或子查询的简单 SELECT 在 10 分钟内 46000 行......这似乎太多了。检查您是否在 StartDate 和 EndDate 上创建并启用了索引。如果是这样,我会选择 mwigdahl o Dems 的答案。

于 2012-01-23T17:40:33.550 回答