首页 > 解决方案 > T-SQL SELECT * 快,SELECT TOP 50 慢

问题描述

(删除了之前的帖子,可能是没有问对方法,我再试试)

    -- 300Ms
    SELECT AppId FROM Application ap
    LEFT OUTER JOIN MissingThings mt on mt.AppId = ap.AppId
    WHERE mt.AppId is NULL
    ORDER BY mt.Id

-- 1.5s
SELECT TOP 50 FROM (TheSame)

    -- 100Ms
    SELECT TOP 50 AppId FROM Application ap
    LEFT OUTER JOIN MissingThings mt on mt.AppId = ap.AppId
    --WHERE mt.AppId is NULL
    ORDER BY mt.Id 

如果我对原始查询应用 TOP,它会变慢。如果没有 TOP,它会快速返回所有 1000 条记录。

如果我删除 WHERE 子句并获得 TOP 50,它又会很快。

还尝试了其他帖子建议将 WHERE 替换为 NOT EXISTS 的方法。没有帮助。

是否有任何一般可能的原因,或者它真的特定于我的数据库?如果是具体的我猜,我不能指望这里的帮助,因为我不允许分享执行计划。

编辑:

WHERE 子句中还有另外 2 个条件,我认为这些条件真的可以忽略,但是一旦我评论了这些条件,原始查询会在 50 毫秒内返回!!!!!!!!!

SELECT TOP 50 AppId FROM Application ap
        LEFT OUTER JOIN MissingThings mt on mt.AppId = ap.AppId
        WHERE mt.AppId is NULL
AND ap.IsOrderFinished = 1
AND ap.IsAssigned = 2
        ORDER BY mt.Id 

在 IsOrderFinished 和 IsAssigned 上添加了非聚集索引 - 对两个或任一索引都没有帮助。

更多结果:

降序速度很快(50 毫秒!) ORDER BY mt.Id DESC(看图)

标签: sql-servertsql

解决方案


有时我无法优化完整的查询,但我可以优化它们的部分。然后,我没有继续尝试优化完整查询,而是将这些部分移动到临时表并使用它们来构建完整查询。

这应该在 300 毫秒而不是 1.5 秒内执行

SELECT AppId 
into #Application
FROM Application ap
     LEFT OUTER JOIN MissingThings mt on mt.AppId = ap.AppId
WHERE mt.AppId is NULL
ORDER BY ap.AppId 

SELECT TOP 50 * FROM #Application

DROP TABLE #Application

我们还尝试使用您最快的查询来加快速度。这应该在接近 100 毫秒内执行。

CREATE TABLE #Application (AppId INT, MissingAppId INT)
CREATE CLUSTERED INDEX #IX_Application ON #Application (MissingAppId, AppId)

INSERT INTO #Application (AppId, MissingAppId)
SELECT ap.AppId, mt.AppId
FROM Application ap
     LEFT OUTER JOIN MissingThings mt on mt.AppId = ap.AppId

SELECT TOP 50 * 
FROM #Application
WHERE MissingAppId IS NULL
ORDER BY AppId

DROP TABLE #Application

推荐阅读