SQL Server 的文档总是有点晦涩难懂,但不一定不正确。您看到的是两种不同事物的信息,SQL 语句的计划指南和模块(存储过程、标量/多语句 UDF)的计划指南。
布丁发酵 1
我将在这里使用 Stack Overflow 数据库的本地副本,并创建此索引。
CREATE INDEX
u
ON dbo.Users
(Reputation)
WITH
(SORT_IN_TEMPDB = ON, DATA_COMPRESSION = PAGE);
然后为语句创建一个计划指南:
EXEC sp_create_plan_guide
@name = N'I Have A Special Plan For This World',
@stmt = N'SELECT u.* FROM dbo.Users AS u WHERE u.Reputation = @Reputation;',
@type = N'SQL',
@params = N'@Reputation integer',
@hints = N'OPTION (OPTIMIZE FOR (@Reputation = 1))';
对于该语句,执行文本中的任何变化都会破坏计划指南。
/*Works, matches*/
DECLARE
@s nvarchar(MAX)= N'SELECT u.* FROM dbo.Users AS u WHERE u.Reputation = @Reputation;',
@p nvarchar(1000) = N'@Reputation integer';
EXECUTE sys.sp_executesql
@s,
@p,
2;
GO
/*Doesn't work, comment*/
DECLARE
@s nvarchar(MAX)= N'SELECT u.* FROM dbo.Users AS u WHERE u.Reputation = @Reputation;--I Have A Special Plan For This World',
@p nvarchar(1000) = N'@Reputation integer';
EXECUTE sys.sp_executesql
@s,
@p,
2;
GO
/*Doesn't work, comment*/
DECLARE
@s nvarchar(MAX)= N'SELECT u.* FROM dbo.Users AS u WHERE u.Reputation = @Reputation;/*I Have A Special Plan For This World*/',
@p nvarchar(1000) = N'@Reputation integer';
EXECUTE sys.sp_executesql
@s,
@p,
2;
GO
/*Doesn't work, new lines*/
DECLARE
@s nvarchar(MAX)= N'
SELECT
u.*
FROM dbo.Users AS u
WHERE u.Reputation = @Reputation;',
@p nvarchar(1000) = N'@Reputation integer';
EXECUTE sys.sp_executesql
@s,
@p,
2;
GO
/*Doesn't work, spacing around =*/
DECLARE
@s nvarchar(MAX)= N'SELECT u.* FROM dbo.Users AS u WHERE u.Reputation=@Reputation;',
@p nvarchar(1000) = N'@Reputation integer';
EXECUTE sys.sp_executesql
@s,
@p,
2;
GO
/*Doesn't work, double spaces*/
DECLARE
@s nvarchar(MAX)= N'SELECT u.* FROM dbo.Users AS u WHERE u.Reputation = @Reputation;',
@p nvarchar(1000) = N'@Reputation integer';
EXECUTE sys.sp_executesql
@s,
@p,
2;
GO
所以,这种类型的计划指南很敏感。
布丁证明
如果我们改用存储过程,则该敏感性不适用。例如:
CREATE OR ALTER PROCEDURE
dbo.GetThatRep
(
@Reputation integer
)
AS
BEGIN
SET NOCOUNT, XACT_ABORT ON;
SELECT
u.*
FROM dbo.Users AS u
WHERE u.Reputation = @Reputation;
END;
EXEC sp_create_plan_guide
@name = N'I Have A Special Plan For This World',
@stmt = N'SELECT u.* FROM dbo.Users AS u WHERE u.Reputation = @Reputation;',
@type = N'OBJECT',
@module_or_batch = N'dbo.GetThatRep',
@hints = N'OPTION (OPTIMIZE FOR (@Reputation = 1))'; ;
GO
/*Works, magically*/
EXEC dbo.GetThatRep
@Reputation = 2;
尽管计划指南和存储过程文本格式之间存在空格差异,但这仍将匹配并按预期工作。
当然,在 Darling Data, LLC 这里,我们会自行清理。
EXEC sp_control_plan_guide
N'DROP',
N'I Have A Special Plan For This World';
GO
不同的世界
SQL Server 的文档总是有点晦涩难懂,但不一定不正确。您看到的是两种不同事物的信息,SQL 语句的计划指南和模块(存储过程、标量/多语句 UDF)的计划指南。
布丁发酵 1
我将在这里使用 Stack Overflow 数据库的本地副本,并创建此索引。
然后为语句创建一个计划指南:
对于该语句,执行文本中的任何变化都会破坏计划指南。
所以,这种类型的计划指南很敏感。
布丁证明
如果我们改用存储过程,则该敏感性不适用。例如:
尽管计划指南和存储过程文本格式之间存在空格差异,但这仍将匹配并按预期工作。
当然,在 Darling Data, LLC 这里,我们会自行清理。