谨慎使用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'
执行计划当然也会是这样的:
只是,只是不知道最终开发大神能改成什么样......
---------------------------------------------------------------
开发大神的解决方案:连接字符串中配置: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: 仅在使用 CHAR、VARCHAR 或 LONGVARCHAR JDBC 类型发送参数时检查.sendStringParametersAsUnicode 属性。 新的 JDBC 4.0 国家字符方法(例如 SQLServerPreparedStatement 和 SQLServerCallableStatement 类的 setNString、setNCharacterStream 和 setNClob 方法)始终将它们的参数值以 Unicode 格式发送到服务器,而不考虑此属性的设置。
为了使 CHAR、VARCHAR 和 LONGVARCHAR JDBC 数据类型获得最佳性能,应用程序应将 sendStringParametersAsUnicode 属性设置为“false”并使用 SQLServerPreparedStatement 和 SQLServerCallableStatement 类的 setString、setCharacterStream 和 setClob 非国家字符方法。 当应用程序将 sendStringParametersAsUnicode 属性设置为“false”并使用非国家字符方法访问服务器端(如nchar、nvarchar 和 ntext)上的 Unicode 数据类型时,如果数据库排序规则不支持非国家字符方法传递的 String 参数中的字符,则某些数据可能丢失。 请注意,对于NCHAR、NVARCHAR 和 LONGNVARCHAR JDBC 数据类型,应用程序应使用 SQLServerPreparedStatement 和 SQLServerCallableStatement 类的 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
谨慎使用MyBatis自动生成Where语句的更多相关文章
- springboot+mybatis+mysql 利用mybatis自动生成sql语句
工具和环境 idea,mysql,JDK1.8 效果图如下 结构图如下 java resources sql文件 /* Navicat MySQL Data Transfer Source Serve ...
- 【MyBatis】MyBatis自动生成代码查询之爬坑记
前言 项目使用SSM框架搭建Web后台服务,前台后使用restful api,后台使用MyBatisGenerator自动生成代码,在前台使用关键字进行查询时,遇到了一些很宝贵的坑,现记录如下.为展示 ...
- Mybatis自动生成实体类
Maven自动生成实体类需要的jar包 一.pom.xml中 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns ...
- 使用mybatis-generator插件结合tk.mybatis自动生成mapper二三事
本篇文章将介绍使用spring boot框架,引入mybatis-generator插件,结合tk.mybatis自动生成Mapper和Entity的一整套流程,其中包括最重要的踩坑与填坑. ...
- mybatis自动生成代码工具(逆向工程)
MyBatis自动生成实体类(逆向工程) MyBatis属于一种半自动的ORM框架,它需要我们自己编写sql语句和映射文件,但是编写映射文件和sql语句很容易出错,所以mybatis官方提供了Gene ...
- 使用mybatis-generator插件结合tk.mybatis自动生成mapper
本篇文章将介绍使用spring boot框架,引入mybatis-generator插件,结合tk.mybatis自动生成Mapper和Entity的一整套流程,其中包括最重要的踩坑与填坑. ...
- mybatis自动生成java代码
SSM框架没有DB+Record模式,写起来特别费劲,只能用下面的方法勉强凑合. 上图中,*.jar为下载的,src为新建的空白目录,.xml配置如下. <?xml version=" ...
- 使用Excel自动生成sql语句
在近一段日子里,进入了新的项目组,由于项目需要,经常要将一些Excel表中的数据导入数据库中,以前并没有过多的接触过数据导入与数据处理,对于我来说比较痛苦,今天下午花了几个小时处理数据,但是同事给我提 ...
- Mybatis 自动生成代码,数据库postgresql
最近做了一个项目,使用Mybatis自动生成代码,下面做一下总结,被以后参考: 一.提前准备: 1.工具类:mybatis-generator-core-1.3.2.jar 2.postgresql驱 ...
随机推荐
- php -- 配置与安装
1.php与apache安装路径 2.安装Apache服务 httpd -k install 开启关闭重启服务 http -k start/stop/restart 3.php.ini-develop ...
- 【Java初探外篇02】——关于静态方法与实例方法
在Java的学习中,我们知道,方法的使用是不可或缺的重要部分,在我们编写第一个Java程序hello world的时候,我们就要开始使用主方法main():它就是一个静态方法(static metho ...
- Windows下编译打包Spice PC客户端
目录 1 环境搭建 2 编译客户端 3 打包客户端 1 环境搭建 1.1 准备工作 安装启动: 安装替换图标工具: Resource Hacker 安装exe制作工具: NSIS(提取码:3dfp ...
- Java 容器源码分析之1.7HashMap
以下内容基于jdk1.7.0_79源码: 什么是HashMap 基于哈希表的一个Map接口实现,存储的对象是一个键值对对象(Entry<K,V>): HashMap补充说明 基于数组和链表 ...
- Mouse点击之后,复制GridView控件的数据行
本篇是实现用mouse点击GridView控件任意一行,把所点击的数据复制至另一个GridView控件上. 实现大概思路,把所点击的数据行的记录主键找出来,再去过滤数据源. 点击功能,已经实现,可以参 ...
- jQuery选择器遇上一些特殊字符
学习jQuery过程中,发现一些特殊字符,如“.”,“#”,"(","]"等.它在选择器应用时,按照普通处理就会出错.解决办法,就是使用转义字符来处理,这有点象 ...
- Windows下当地RabbitMQ服务的安装
Windows下本地RabbitMQ服务的安装 本文参考:刘若泽相关技术文档 当然这些内容页可以通过RabbitMQ官方网站获得. RabbitMQ配置说明手册 一.RaibbitMQ服务器配置 1. ...
- 【题解】LFYZNoip前水题赛 T6
垃圾出题人们在30分钟内完成了讨论,出题,命题,造数据,跑std的所有环节 luv的化学竞赛题 题目背景 luv_letters 在肝化学竞赛题,他的梦想是混个省一,但是遗憾的是他今年的省二莫名消失了 ...
- 推荐《Java编程思想》
最近看了(美)Bruce Eckel 著<Java编程思想>,还没有看完,但是极力推荐.尤其是学完一遍基础之后,再看很有感觉.之前学习基础的时候就买了这本书,那时候也真心看不下去,包括现在 ...
- 【ZeroMQ】1、ZeroMQ(java)入门之Requerst/Response模式
自己最开始是在cloud foundry中接触过消息服务器(nats),或者说是消息中间件,也算是初步知道了一个消息服务器对于分布式的网络系统的重要性,后来自己也曾想过在一些项目中使用它,尤其是在一些 ...