如何在SQL Server中选择TOP(@x)或简单地“全部”行(没有SET ROWCOUNT)

时间:2016-09-21 15:21:35

标签: sql-server

我有一个标志,用于确定结果集是否应限制为小尺寸。查询本身很大,我不想复制/粘贴它,因为维护会很糟糕。什么是最好的方式?我有一些我正在玩的替代方案,但它们对我来说似乎是黑客攻击:

可能性#1

SELECT TOP (
    CASE WHEN @flag = 1 THEN @limit ELSE @someHugeNumber END
) (...)
FROM (...) hugeQuery;

可能性#2

DECLARE @rc INT = CASE WHEN @flag = 1 THEN @limit ELSE 0 END;
SET ROWCOUNT @rc;
SELECT (...) FROM (...) hugeQuery;

有更好的方法吗?性能怎么样?帮助赞赏!

1 个答案:

答案 0 :(得分:3)

WITH    q AS
        (
        /* my huge query */ 
        )
(
SELECT  TOP (@limit)
        *
FROM    q
WHERE   @flag = 1
)
UNION ALL
(
SELECT  *
FROM    q
WHERE   @flag = 0
)
ORDER BY
        somefield
OPTION (RECOMPILE)

OPTION (RECOMPILE)会使优化器嗅探@flag的值并优化任一查询。但是,在每次调用时都需要重新编译查询。

如果你把它关掉,那么两个查询很可能会使用合并联合算法连接起来,这实际上具有几乎相同的性能(因为其中一个查询总是为空的),只要巨大的查询输出按somefield排序。