有幾種方法,但你可能會注意到這些都看起來很醜或不必要的複雜。此外,你真的需要那個ORDER BY嗎?
你可以使用TOP (100) PERCENT
和查看,但百分比只有當你真的不需要那麼貴ORDER BY
,因爲SQL Server將忽略你的工作,如果ORDER BY
你試試吧。
我建議採取的存儲過程的優勢,但首先讓解釋特效類型的區別:
硬編碼參數嗅探
--Note the lack of a real parametrized column. See notes below.
IF OBJECT_ID('[dbo].[USP_TopQuery]', 'U') IS NULL
EXECUTE('CREATE PROC dbo.USP_TopQuery AS ')
GO
ALTER PROC [dbo].[USP_TopQuery] @MaxRows NVARCHAR(50)
AS
BEGIN
DECLARE @SQL NVARCHAR(4000) = N'SELECT * FROM dbo.ThisFile'
, @Option NVARCHAR(50) = 'TOP (' + @MaxRows + ') *'
IF ISNUMERIC(@MaxRows) = 0
EXEC sp_executesql @SQL
ELSE
BEGIN
SET @SQL = REPLACE(@SQL, '*', @Option)
EXEC sp_executesql @SQL
END
END
本地變量參數嗅探
IF OBJECT_ID('[dbo].[USP_TopQuery2]', 'U') IS NULL
EXECUTE('CREATE PROC dbo.USP_TopQuery2 AS ')
GO
ALTER PROC [dbo].[USP_TopQuery2] @MaxRows INT NULL
AS
BEGIN
DECLARE @Rows INT;
SET @Rows = @MaxRows;
IF @MaxRows IS NULL
SELECT *
FROM dbo.THisFile
ELSE
SELECT TOP (@Rows) *
FROM dbo.THisFile
END
無參數嗅探,老方法
IF OBJECT_ID('[dbo].[USP_TopQuery3]', 'U') IS NULL
EXECUTE('CREATE PROC dbo.USP_TopQuery3 AS ')
GO
ALTER PROC [dbo].[USP_TopQuery3] @MaxRows INT NULL
AS
BEGIN
IF @MaxRows IS NULL
SELECT *
FROM dbo.THisFile
ELSE
SELECT TOP (@MaxRows) *
FROM dbo.THisFile
END
請注意有關參數嗅探:
的SQL Server在時間編譯初始化中存儲的特效變量,當它不解析。
這意味着,SQL Server將無法猜測查詢,並會 選擇用於查詢的最後一個有效的執行計劃,無論 無論是就算不錯了。
有兩種方法,硬編碼允許優化器猜測的局部變量。
的參數嗅探
- 使用sp_executesql的硬編碼,不僅重用了查詢,但防止SQL注入。
- 然而,在這種類型的查詢,就不會總是表現基本更好,因爲Top運算符是不是列或表(這樣的語句有效地在這個版本我用沒有變量)當時
- 統計創建編譯計劃將決定如果對謂詞沒有使用變量(
ON
,,HAVING
) - 可以使用選項或提示來
RECOMPILE
來解決此問題,方法效果如何。
變量參數嗅探
- 可變放慢參數嗅探,在另一方面,有足夠的靈活性witht統計工作在這裏,在我自己的測試,似乎變量參數具有的優勢使用統計信息查詢(特別是在我更新了統計數據後)。

最終,性能的問題是關於哪一種方法將使用最少的步量通過小葉遍歷。 統計,行在您的表中,和規則爲SQL Server將決定使用掃描VS Seek影響性能。
運行不同值會顯示性能顯着變化,但通常優於USP_TopQuery3。所以不要假設一種方法一定比另一種更好。
- 另外請注意,您可以使用一個表值函數做同樣的,但戴夫皮納爾會說:
如果你要回答「爲了避免重複代碼,您使用 函數' - 請認真思考!存儲過程可以做同樣的...
如果你要回答 '功能可以在SELECT中使用,而存儲過程不能使用' ' - 再想一想!
SQL SERVER – Question to You – When to use Function and When to use Stored Procedure
什麼是從設置的參數到2147483647默認阻止你? –
你基本上設置了一個視圖閾值。爲什麼不設置系統範圍的閾值,然後在用戶級別覆蓋? 我的意思是..有一個sysmax = 1000,然後檢索usermax ...比較它不應該超過sysmax ...理想情況下,你不應該在視圖中顯示的一切..特別是所有列 – maSTAShuFu
我認爲你的問題的一部分是你想知道是否有一個開銷來設置一個最大值遠高於實際記錄。一切都告訴我不應該有。此外,如果您的表格正確索引,則開銷(如果有的話)可以忽略不計。 – DaniDev