MyBatis自动生成Where语句

 更新时间:2016年08月11日 09:41:08   作者:万剑齐发  
这篇文章主要介绍了MyBatis自动生成Where语句的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下

最近监控到类似这样一个慢查询:

select delete_flag,delete_time
from D_OrderInfo 
   WHERE ( OrderId is not null and
          OrderId = N'xxxx') 

D_OrderInfo表上有一个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 delete_flag,delete_time
from D_OrderInfo 
   WHERE OrderId = 'xxxx'

执行计划当然也会是这样的:

只是,只是不知道最终开发大神能改成什么样......

开发大神的解决方案:连接字符串中配置:

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 参数将使用数据库默认的排序规则发送到服务器。

参考:

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

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

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

相关文章

  • JavaScript的基本类型值-String类型

    JavaScript的基本类型值-String类型

    String类型用于表示由零或多个16位Unicode字符组成的字符序列,即字符串。在JavaScript中没有单个的字符型,都是字符串。这篇文章主要介绍了JavaScript的基本类型值String类型,需要的朋友可以参考下
    2017-02-02
  • 浅析Java常用API(Scanner,Random)匿名对象

    浅析Java常用API(Scanner,Random)匿名对象

    这篇文章主要介绍了Java常用API(Scanner,Random)匿名对象,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • Spring入门实战之Profile详解

    Spring入门实战之Profile详解

    什么是spring profile?简单讲profile就是一组配置,不同profile提供不同组合的配置,程序运行时可以选择使用哪些profile来适应环境。下面这篇文章主要介绍了Spring中Profile实战的相关资料,需要的朋友可以参考借鉴。
    2017-02-02
  • springboot中的starter使用解析

    springboot中的starter使用解析

    这篇文章主要介绍了springboot中的starter使用解析,引入了starter依赖之后,基础组件就可以像在spring的bean一样在项目中使用,那其实只要找到在哪里加载了这些bean就明白了,需要的朋友可以参考下
    2023-10-10
  • Jmeter设置全局变量token过程图解

    Jmeter设置全局变量token过程图解

    这篇文章主要介绍了Jmeter设置全局变量token过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • 简单了解JavaBean作用及常用操作

    简单了解JavaBean作用及常用操作

    这篇文章主要介绍了简单了解JavaBean作用及常用操作,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • Spring Cloud超详细i讲解Feign自定义配置与使用

    Spring Cloud超详细i讲解Feign自定义配置与使用

    这篇文章主要介绍了SpringCloud Feign自定义配置与使用,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • 关于java方法区详解

    关于java方法区详解

    这篇文章主要介绍了关于java方法区的使用解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • java自带的MessageDigest实现文本的md5加密算法

    java自带的MessageDigest实现文本的md5加密算法

    这篇文章主要介绍了java自带的MessageDigest实现文本的md5加密算法,需要的朋友可以参考下
    2015-12-12
  • 老生常谈Java动态编译(必看篇)

    老生常谈Java动态编译(必看篇)

    下面小编就为大家带来一篇老生常谈Java动态编译(必看篇)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05

最新评论