如何避免整数列的隐式转换

meh*_*hah 4 sql-server optimization execution-plan type-conversion

  SELECT [BusinessEntityID],[NationalIDNumber],[LoginID],[OrganizationNode]
  FROM [AdventureWorks2014].[HumanResources].[Employee]
  where BusinessEntityID = 5
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

在实际执行计划中执行查询后,我得到了 SQL Server 调用的 convert_implicit() 函数。

  SELECT [BusinessEntityID],[NationalIDNumber],[LoginID],[OrganizationNode]
  FROM [AdventureWorks2014].[HumanResources].[Employee]
  where BusinessEntityID = convert(int,5)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

显然,当我将标量值显式转换为整数类型时,不会调用 convert_implicit() 函数。有什么方法可以避免在不使用显式转换的情况下对标量 int 值进行隐式转换。另外我想知道隐式转换、显式转换和根本没有转换之间的性能差异。

Mar*_*ith 10

如何避免整数列的隐式转换

隐式转换的是参数,而不是列。

查询已通过 SQL Server进行简单参数化。您无法控制此过程中使用的数据类型。它使用可以保存文字值的最小数据类型(5可以放入 a tinyint)。将tinyint参数隐式转换为 anint不会导致任何问题。

然而,为了避免在高速缓存多个计划intsmallinttinyint并摆脱你能明确自己的参数化查询的隐式转换的-用数据类型的参数int,而不是它被自动参数化。

EXEC sys.sp_executesql
  N'SELECT [BusinessEntityID],[NationalIDNumber],[LoginID],[OrganizationNode]
  FROM [AdventureWorks2014].[HumanResources].[Employee]
  where BusinessEntityID = @BusinessEntityID',
  N'@BusinessEntityID INT',
  @BusinessEntityID = 5; 
Run Code Online (Sandbox Code Playgroud)

另一种替代方法是通过添加AND 1=1如下冗余来阻止简单的参数化。但我不建议这样做,因为那样你会为你传递的每个不同的文字值编译和缓存计划。

SELECT [BusinessEntityID],
       [NationalIDNumber],
       [LoginID],
       [OrganizationNode]
FROM [AdventureWorks2014].[HumanResources].[Employee]
where BusinessEntityID = 5 
      AND 1=1
Run Code Online (Sandbox Code Playgroud)