博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SQLServer数据类型优先级对性能的影响 (转)
阅读量:6377 次
发布时间:2019-06-23

本文共 1838 字,大约阅读时间需要 6 分钟。

问题:

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

 

解决方案:

         出现这种微秒的问题原因可能是作为参数的数据类型与查询中的数据类型不一致。在这种情况下,SQLServer将会要么把where中的列,要么把参数的数据类型隐式转换为更高级或者更低级的数据类型。当作为被查询列被转换时(转换竞争中的牺牲者),将引起扫描(scan)来满足查询请求。让我们看看以下两个例子,第一个例子使用示例数据库,我们将通过一个客户的AccountNumber在Sales.Customer表中查询这个客户。AccountNumber这一列的数据类型是varchar(10)并且上面有一个唯一索引。运行下面的查询并且查看执行计划,可以看到结果如我们所愿:

 

create proceduredbo.PrecedenceTest

(

 @AccountNumber varchar(10)

)

as

begin

 set nocount on

 select *

 from Sales.Customer

 where AccountNumber = @AccountNumber

end

go

exec dbo.PrecedenceTest'AW00030113'

go

 执行计划如下:

 

 

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

alter procedure dbo.PrecedenceTest
(
@AccountNumber nvarchar(10)
)
as
begin
set nocount on
select *
 from Sales.Customer
where AccountNumber = @AccountNumber
end
go
exec dbo.PrecedenceTest 'AW00030113'
go

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

 

 

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

 

 

 

现在让我们验证一下,在较低级别的数据类型作为查找参数下的情况。在这个例子中,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)

转载地址:http://fwtqa.baihongyu.com/

你可能感兴趣的文章
先安装.Framework然后再安装IIS,ASP.NET程序不能运行
查看>>
NPOI Excel下拉项生成设置
查看>>
360该不该拍?
查看>>
用Xib创建控制器
查看>>
oracle的sqlplus和dos的中文乱码问题
查看>>
LVS+keepalived高可用负载均衡集群部署(二)---LAMP网站服务器与LVS服务器
查看>>
Struts2之简单数据类型转换
查看>>
python 打印数字
查看>>
iptables规则的查看、添加、删除和修改
查看>>
打开网站显示输入用户名和密码
查看>>
size_t的32位和64位兼容
查看>>
HBase全分布式模式的安装和配置
查看>>
Spring 框架的设计理念与设计模式分析
查看>>
十年web老兵整理的前端视频资料
查看>>
工作线程数究竟要设置为多少
查看>>
10个Python 统计报表/图表图形类库
查看>>
关于 xargs 参数被截断,tar 文件被覆盖的问题
查看>>
CentOS 6.3 上安装 Oracle 11g R2(转)
查看>>
js实现滚动新闻效果
查看>>
Nginx出现could not build the server_names_hash 解决办法
查看>>