天天看点

SQLServer数据类型优先级对性能的影响问题:解决方案:补充:数据类型的优先级,从高到底:

译自:

<a href="http://www.mssqltips.com/sqlservertip/2749/sql-server-data-type-precedence/?utm_source=dailynewsletter&amp;utm_medium=email&amp;utm_content=headline&amp;utm_campaign=2012814">http://www.mssqltips.com/sqlservertip/2749/sql-server-data-type-precedence/?utm_source=dailynewsletter&amp;utm_medium=email&amp;utm_content=headline&amp;utm_campaign=2012814</a>

         我在我的应用程序中使用简单的查询/存储过程访问一个很大的表。但执行了很长时间。在where子句中,我使用了有索引并且高选择性(selective)并且没有用函数包裹的字段。但是看起来就像没有使用索引一样,问题出在那里?

create proceduredbo.PrecedenceTest

(

 @AccountNumber varchar(10)

)

as

begin

 set nocount on

 select *

 from Sales.Customer

 where AccountNumber = @AccountNumber

end

go

exec dbo.PrecedenceTest'AW00030113'

 执行计划如下:

SQLServer数据类型优先级对性能的影响问题:解决方案:补充:数据类型的优先级,从高到底:

接着让我们在参数上做些小改动,把它改为nvarchar(10),然后重新执行语句:

执行计划显示,优化器选择了扫描TerritoryID上的索引。

SQLServer数据类型优先级对性能的影响问题:解决方案:补充:数据类型的优先级,从高到底:

检查Filter操作,可以看到AccountNumber列上被隐式转换了类型来匹配传入的参数。由于数据类型varchar比参数类型nvarchar级别更低,导致其所在的索引失效。

SQLServer数据类型优先级对性能的影响问题:解决方案:补充:数据类型的优先级,从高到底:

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

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

SQLServer数据类型优先级对性能的影响问题:解决方案:补充:数据类型的优先级,从高到底:

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

SQLServer数据类型优先级对性能的影响问题:解决方案:补充:数据类型的优先级,从高到底:

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

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

user-defined data types (highest)

sql_variant

xml

datetimeoffset

datetime2

datetime

smalldatetime

date

time

float

real

decimal

money

smallmoney

bigint

int

smallint

tinyint

bit

ntext

text

image

timestamp

uniqueidentifier

nvarchar (including nvarchar(max) )

nchar

varchar (including varchar(max) )

char

varbinary (including varbinary(max) )

binary (lowest)