现在让我们验证一下,在较低级别的数据类型作为查找参数下的情况。在这个例子中,Person.Person 表的LastName列是nvarchar类型,并且上面存在一个可用的索引,存储过程传入的参数是varchar类型:


alter procedure dbo.PrecedenceTest(
@LastName varchar(50)
)
as
begin
set nocount on
select *
from Person.Person
where LastName = @LastName
end
go
exec dbo.PrecedenceTest 'Tamburello'
go


  执行计划显示,优化器选择使用了索引查找:

  点开Index Seek的详细信息,可以看到列LastName的数据类型因为传入参数的原因而隐式转换成更高级的nvarchar类型。

  当索引列不再被转换所影响时,优化器可以自由地选择优执行计划。

  不管你是在应用程序或者在存储过程中定义查询参数,确保查询参数中的数据类型和查询列的数据类型相吻合能避免索引扫描和其他转换引起的问题。

  补充:数据类型的优先级,从高到底:

  1、user-defined data types (highest)
  2、sql_variant
  3、xml
  4、datetimeoffset
  5、datetime2
  6、datetime
  7、smalldatetime
  8、date
  9、time
  10、float
  11、real
  12、decimal
  13、money
  14、smallmoney
  15、bigint
  16、int
  17、smallint
  18、tinyint
  19、bit
  20、ntext
  21、text
  22、image
  23、timestamp
  24、uniqueidentifier
  25、nvarchar (including nvarchar(max) )
  26、nchar
  27、varchar (including varchar(max) )
  28、char
  29、varbinary (including varbinary(max) )
  30、binary (lowest)