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

相关文章

  • java类的定义与使用举例详解

    java类的定义与使用举例详解

    这篇文章主要给大家介绍了关于java类的定义与使用的相关资料,类的方法是用来定义类的行为,在方法中通过操作类的成员变量、编写业务逻辑、返回 结果等实现类的业务行为,需要的朋友可以参考下
    2023-11-11
  • SpringBoot框架底层原理解析

    SpringBoot框架底层原理解析

    这篇文章主要介绍了SpringBoot底层原理,包括配置优先级的配置方式给大家讲解的非常详细,需要的朋友可以参考下
    2024-03-03
  • Java下变量大小写驼峰、大小写下划线、大小写连线转换

    Java下变量大小写驼峰、大小写下划线、大小写连线转换

    有时候需要处理对象属性的getter、setter方法,或者将属性与数据表字段进行相互转换,感兴趣的可以了解一下
    2021-06-06
  • Java事件机制要素及实例详解

    Java事件机制要素及实例详解

    这篇文章主要介绍了Java事件机制要素及实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • java项目新建遇到的两个问题解决

    java项目新建遇到的两个问题解决

    创建一个新的Java项目可以通过多种方式进行,包括使用集成开发环境(IDE)或手动创建,下面这篇文章主要给大家介绍了关于java项目新建遇到的两个问题,需要的朋友可以参考下
    2024-06-06
  • Java代码里如何拼接SQL语句到mybatis的xml

    Java代码里如何拼接SQL语句到mybatis的xml

    这篇文章主要介绍了Java代码里拼接SQL语句到mybatis的xml操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • Java编程线程同步工具Exchanger的使用实例解析

    Java编程线程同步工具Exchanger的使用实例解析

    这篇文章主要介绍了Java编程线程同步工具Exchanger的使用实例解析,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-02-02
  • 解决Java Calendar类set()方法的陷阱

    解决Java Calendar类set()方法的陷阱

    这篇文章主要介绍了解决Java Calendar类set()方法的陷阱,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • Springboot 整合RabbitMq(用心看完这一篇就够了)

    Springboot 整合RabbitMq(用心看完这一篇就够了)

    这篇文章主要介绍了Springboot 整合RabbitMq(用心看完这一篇就够了),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • 浅谈一下SpringBoot中的异步任务

    浅谈一下SpringBoot中的异步任务

    这篇文章主要介绍了浅谈一下SpringBoot中的异步任务,SpringBoot 中的异步任务主要是指在 SpringBoot 中使用异步线程完成处理任务,在 SpringBoot 中使用异步线程非常简单,只需要两个注解就可以搞定,需要的朋友可以参考下
    2023-10-10

最新评论