slqserver数据类型优先级的一个问题

生产中使用sqlserver往往会遇到一些开发同学不曾注意的数据库细节,前些天有个开发同学看到jdbc的连接有一段这样的代码:

dbcp.url=jdbc:sqlserver://xxxx:xxxx;DatabaseName=xxxx;sendStringParametersAsUnicode=false

主要是:

sendStringParametersAsUnicode=false

开发同学说,这个是什么鬼,以前从来没有人教我这样写过,为什么要加这个?

看这样一个简单的sql,tableA是一个大表,1000w吧,uuid还是主键。

Select * from tableA where uuid = #{uuid}

从sqlserver客户端跑

Select * from tableA where uuid = 'xxxxxxxxxxx'

速速杠杠的,它告诉你,查询只需要0ms

但是我可以负责任人的告你,在3年前的系统,抓一些cpu利用率高的sql,发现竟然有很大比例是这么一个简单的sql。

如果觉得奇怪,不合理,完全不用。要知道,代码的世界没有奇怪,只是你可能忽略了某一个你不清楚的东西。

调试的时候发现#{uuid}实际到数据库的执行方式发生了微妙的变化。

uuid字段在数据库是varchar类型的,Sqlserver默认的编码方式是ANSI的方式,而java是Unicode。默认的jdbc连接

sendStringParametersAsUnicode=true

看一看sqlserver 数据类型优先级,当两个不同数据类型的表达式用运算符组合后,数据类型优先级规则指定将优先级较低的数据类型转换为优先级较高的数据类型。如果此转换不是所支持的隐式转换,则返回错误。当两个操作数表达式具有相同的数据类型时,运算的结果便为该数据类型。
http://msdn.microsoft.com/zh-cn/library/ms190309(v=sql.105).aspx

看排序的第25到27

uniqueidentifier
nvarchar(包括 nvarchar(max))
nchar
varchar(包括 varchar(max))
char

nvarchar排在了varchar前面,nvarchar优先级高,数据库就把uuid整列都转换为nvarchar类型,然后再执行查询,这样的查询在数据量大的情况下就OVER了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值