答案 0 :(得分:0)
这是一个ad-hoc
查询。引擎只会忽略您的变量,并建立一个执行计划,无论变量的值如何,该计划都可用于每个查询。例如,让我们生成一些数据:
DROP TABLE IF EXISTS [dbo].[DataSource];
CREATE TABLE [dbo].[DataSource]
(
[ID] INT IDENTITY(1000, 1) PRIMARY KEY
,[DateTimeCreated] DATETIME2
,[SampleText] NVARCHAR(4000)
);
CREATE INDEX IX_DateTimeCreated ON [dbo].[DataSource] ([DateTimeCreated]);
INSERT INTO [dbo].[DataSource] ([DateTimeCreated], [SampleText])
SELECT SYSDATETIME()
,LEFT(REPLICATE([number], 3500), 3500)
FROM [master]..[spt_values];
UPDATE [dbo].[DataSource]
SET [DateTimeCreated] = '2018-01-01'
WHERE [ID] < 1051;
GO
,并将50条记录设置为日期2018-01-01
。现在,清除缓冲区和缓存(不要在生产SQL实例上执行)并分别运行以下查询:
DBCC DROPCLEANBUFFERS;
DBCC FREEPROCCACHE;
GO
DECLARE @filter DATETIME2 = '2018-01-01'
SELECT *
FROM [dbo].[DataSource]
WHERE [DateTimeCreated] = @filter;
GO
SELECT *
FROM [dbo].[DataSource]
WHERE [DateTimeCreated] = '2018-01-01';
您将看到引擎为每个查询建立单独的执行计划,并且您可以像示例中一样执行计划(变量值将被忽略):
SELECT cacheobjtype, objtype, text,usecounts
FROM sys.dm_exec_cached_plans
CROSS APPLY sys.dm_exec_sql_text(plan_handle)
WHERE [objtype] = 'Adhoc'
AND [text] LIKE '%2018-01-01%'
AND [text] NOT LIKE '%dm_exec_cached_plans%'
ORDER BY usecounts DESC;
如果您要强制引擎根据变量值构建计划,则可以使用recompile
选项或WITH INDEX
提示:
DECLARE @filter DATETIME2 = '2018-01-01'
SELECT *
FROM [dbo].[DataSource]
WHERE [DateTimeCreated] = @filter
OPTION (RECOMPILE);
GO
DECLARE @filter DATETIME2 = '2018-01-01'
SELECT *
FROM [dbo].[DataSource] WITH (INDEX = IX_DateTimeCreated)
WHERE [DateTimeCreated] = @filter;
GO
在某些情况下,我需要提供索引提示,但通常情况下最好具有正确的索引,进行常规索引维护并编写易于引擎理解和优化而又不易于理解的T-SQL语句担心他的工作方式。
在您的情况下,该语句非常简单,因此我认为这只是忽略默认值以加快即席查询的一些默认行为。您可以将语句包装在存储过程中,然后再次查看缓存计划和执行计划。