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

来源:互联网 发布:tensorflow linux 编辑:程序博客网 时间:2024/05/21 22:40

生产中使用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

uniqueidentifiernvarchar(包括 nvarchar(max))ncharvarchar(包括 varchar(max))char

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

0 0
原创粉丝点击