临时表上的SQL交叉联接速度较慢

临时表上的SQL交叉联接速度较慢,sql,sql-server,join,cross-join,tempdb,Sql,Sql Server,Join,Cross Join,Tempdb,已将以下代码添加到我的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

已将以下代码添加到我的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小时左右,是否有人对原因有任何建议,没有交叉连接的结果约为46000行,之后又返回了231行,即根据查询被归类为“非累积”的任何内容。

我猜这是一个非常简化的示例?所以我不能给出具体的答案,但简单的回答是,查询的累积部分比非累积部分做了更多的工作

试试这两个做比较

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))));
我预计后者需要更长的时间

此外,对于优化者来说,合并多个业务逻辑片段的条件可能非常困难。这意味着以下结构可能更有效

SELECT * FROM <non cumulative query>
UNION ALL
SELECT * FROM <cumulative query>

我猜这是一个非常简单的例子?所以我不能给出具体的答案,但简单的回答是,查询的累积部分比非累积部分做了更多的工作

试试这两个做比较

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))));
我预计后者需要更长的时间

此外,对于优化者来说,合并多个业务逻辑片段的条件可能非常困难。这意味着以下结构可能更有效

SELECT * FROM <non cumulative query>
UNION ALL
SELECT * FROM <cumulative query>

我不明白为什么这里需要交叉连接构造-这只是混淆了问题。我将该查询重写为:

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))));

这应该是等效的,但更清楚地说明了您正在做什么。假设此联合的第一部分是您以前拥有的,第二部分是较慢的,那么很可能EndDate或实际查询中的任何等效项没有正确索引,导致过度扫描。发布您的执行计划以进行更详细的分析。

我不明白您为什么需要在此处使用交叉连接构造-这只是混淆了问题。我将该查询重写为:

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))));

这应该是等效的,但更清楚地说明了您正在做什么。假设此联合的第一部分是您以前拥有的,第二部分是较慢的,那么很可能EndDate或实际查询中的任何等效项没有正确索引,导致过度扫描。发布您的执行计划以进行更详细的分析。

10分钟内完成46000行的简单选择,无需连接或子查询。。。这似乎太过分了。检查是否已在StartDate和EndDate上创建并启用索引。如果是这样,我选择mwigdahl o Dems答案。

10分钟内选择46000行,进行简单选择,无需连接或子查询。。。这似乎太过分了。检查是否已在StartDate和EndDate上创建并启用索引。如果是这样,我会选择mwigdahl o Dems的答案。

根据我现有的答案;我建议使用UNION ALL,这样乐观主义者甚至不会开始尝试去重复记录集。结果将是相同的,但在更短的时间内,这并没有加快处理时间,根据我现有的答案;我建议使用UNION ALL,这样乐观主义者甚至不会开始尝试去重复记录集。结果将是相同的,但在更短的时间内,这并没有加快处理时间