严谨用MyBatis自动生成Where语句

近些年监控及接近这样一个缓查询:

select XX_time
from XXOrderInfo 
     WHERE (  OrderId is not null and
                   OrderId = N'xxxx') 

xxOrderInfo表上有一个OrderId的索引,但OrderId字段是Varchar类型。
由于开发框架MyBatis自动生成Where条件不会指定参数类型,字符串类型的参数到了SQLServer里就自动成了NVARCHAR(4000)类型了,
坑人的是,不指定参数类型也就罢了,还自动加了个OrderId Is NOT NULL这样一个非SARG的条件,执行计划成了这样:

---------------------------------------------------------------------------------------------
如果没有OrderId IS NOT NULL这个条件,执行计划会是这样的:

 

由于参数类型Nvarchar比索引字段类型varchar优先级要高,不能直接转换,但SQLServer优化器最终还是将他转成了一个范围值,最终的等号查询也变成了类似一个小范围查询。
可以从Index Seek这一步的详细信息可以看出:

 

------------------------------------------------------------------------
如果参数类型匹配,那么执行计划会是想象中的那样(虽然没有包含到,还是有Key Lookup):

 

--------------------------------------------------------------------------------------
当然,有点小小强迫症的我最终希望的写法是这样的:

select XXXX_time
from XXOrderInfo 
     WHERE OrderId = 'xxxx'

尽计划自也会是如此的:

图片 1

 

只是,只是不知道最终开发大神能改成什么样......
---------------------------------------------------------------
开发大神的解决方案:连接字符串中配置:sendStringParametersAsUnicode=false
---------------------------------------------------------------
后记:

默认情况下,Java 中之字符数据作为 Unicode 进行拍卖;Java String 对象表示
Unicode 字符数量。在 JDBC 驱动程序中,唯一可免听命这个规则的凡 ASCII 流
getter 和 setter
方法,这属于比较独特的图景,因为这些措施运用的字节流带有单个已掌握代码页
(ASCII) 的隐式假定。
除此以外,JDBC 驱动程序提供了 sendStringParametersAsUnicode
连接字符串属性。此属性可用于指定作为 ASCII 而未是 Unicode
来发送的字符数据的预定义参数。
用作性能方面的一致起加强功能,可以经安装 sendStringParametersAsUnicode
连接字符串属性将 String 参数为非 Unicode 格式传递至 SQL Server。

如果 sendStringParametersAsUnicode 属性设置为“true”,String 参数将以
Unicode 格式发送到服务器。
如果 sendStringParametersAsUnicode 属性设置也“false”,String
参数将为非 Unicode 格式(如 ASCII/MBCS )而未是 Unicode
格式发送至服务器。
 sendStringParametersAsUnicode 属性的默认值为“true”。 Note: 仅于用 CHARVARCHAR 或 LONGVARCHAR JDBC
类型发送参数时检查.sendStringParametersAsUnicode 属性。 新的 JDBC
4.0
国家字符方法(例如 SQLServerPreparedStatement.aspx) 和 SQLServerCallableStatement.aspx) 类的
setNString、setNCharacterStream 和 setNClob 方法)始终用她的参数值为
Unicode 格式发送至服务器,而无考虑此属性的安。

为了使 CHARVARCHAR 和 LONGVARCHAR JDBC
数据类型获得最佳性能,应用程序应将 sendStringParametersAsUnicode 属性设置也“false”并使 SQLServerPreparedStatement.aspx) 和 SQLServerCallableStatement.aspx) 类的
setString、setCharacterStream 和 setClob 非江山字符方法。
当应用程序将 sendStringParametersAsUnicode 属性设置也“false”并利用非国家字符方法访问服务器端(如ncharnvarchar 和 ntext)上之
Unicode 数据类型时,如果数据库排序规则不支持非国家字符方法传递的 String
参数中之字符,则某些数据或者丢掉。
请注意,对于NCHARNVARCHAR 和 LONGNVARCHAR JDBC
数据类型,应用程序应下 SQLServerPreparedStatement.aspx) 和 SQLServerCallableStatement.aspx) 类的
setNString、setNCharacterStream 和 setNClob 国家字符方法。

参考:

http://d.hatena.ne.jp/gnarl/20110706/1309945379

https://technet.microsoft.com/zh-cn/library/ms378857(SQL.110).aspx

https://technet.microsoft.com/zh-cn/library/ms378988(v=sql.110).aspx

 
网站地图xml地图