如果该列的类型强制转换为完全相同的数据类型和长度,而seek谓词是一个文字,则确实确实忽略了它或将其视为no-op,并且对相等性进行了索引查找。
Seek Keys[1]: Prefix: [tempdb].[dbo].[#test].name = Scalar Operator(N'rpc')
如果列的强制类型转换为相同的数据类型但长度更大,并且查找谓词是字符串文字,则会导致索引扫描。这显然是可以避免的。
如果列的类型转换为相同的数据类型且长度相同或更大,并且查找谓词是局部变量,则它将计算标量运算符添加到执行计划中。这将调用GetRangeThroughConvert
并输出一个范围。
该范围用于进行索引查找,看起来非常有效
Seek Keys[1]:
Start: [tempdb].[dbo].[#test].name > Scalar Operator([Expr1006]),
End: [tempdb].[dbo].[#test].name < Scalar Operator([Expr1007])
测试代码
SELECT *
INTO #test
FROM [master].[dbo].[spt_values]
CREATE NONCLUSTERED INDEX [ixname] ON #test
(
[name] ASC
)
DECLARE @name NVARCHAR(MAX)
SET @name = 'rpc'
SELECT name
FROM #test
WHERE CAST(name AS NVARCHAR(35))= @name --Cast the same and local variable
SELECT name
FROM #test
WHERE CAST(name AS NVARCHAR(MAX))=@name --Cast to longer and local variable
SELECT name
FROM #test
WHERE CAST(name AS NVARCHAR(35))='rpc' --Cast the same and literal
SELECT name
FROM #test
WHERE CAST(name AS NVARCHAR(MAX))='rpc' --Cast to longer and literal