- 浏览: 115771 次
文章分类
2年前上线的系统了,运行两年了啊(意思是忍受了这么慢的查询很久了)!!!
——正式开始之前,先吐吐槽。。。。。
场景描述:系统中查询条件涉及日期的所有操作,都会导致数据库IO开销突增。
-------------------------------------------------------------------------
解决过程:
0.检查日期字段,看其上有无索引,这个是有的
1.拉下来项目代码,配置jrebel,配置log4j,启动项目
2.登录系统,查询,拉取控制台SQL,手动补齐参数值,执行,看执行计划。速度快开销小,木发现有大问题…… 纳闷。。。。。不解。。。。。
3.设置log4j,重启项目,重新执行2:
1)修改
log4j.rootLogger=INFO, stdout
2)新增
log4j.logger.org.hibernate.type=TRACE
log4j.logger.org.hibernate.sql=TRACE
4.查看对日期字段绑定的日期值的类型,竟然是TimeStampType!!!肿么会这样???传进去的值明明是Date类型的。。。。。这样查询不会走索引,而且要把日期列的每个值都转换成时间戳类型再跟传入的值比较。。。。。介个隐式数据类型转换也太神奇了吧
5.将所有类似
hql.append(" and table_name.d_column_name = :d_column_name");
的语句改为
hql.append(" and table_name.d_column_name = cast(:d_column_name as date)");
这样虽然我Trace到的还是TimeStampType,但是在查询里转换成Oracle DATE类型了,就可以走索引了。
问题解决。
-------------------------------------------------------------------------
疑惑:
1.出现这种问题原因是什么?肯定不是日期格式的问题,因为要在页面上设定日期范围的查询,虽然传入字符串并转为短日期格式传入,最后Trace到的还是时间戳类型。不明白,hibernate明明是有DateType的啊。
2.有没有方法可以通过配置hibernate一次性解决这种日期类型转换为时间戳类型的问题?
以上两个疑惑,苦逼DBA问过开发,他们也不知道……
后记:EM中也可以排查到这个问题:Advisor Central>Advisors>Advisor Tasks>Advisory Type = SQL Tuning Advisor > Go > View Result > Overall Task Statistics > Restructure SQL > Select one line> View Recommendations
Type
Restructure SQL
Findings
The predicate "table_name"."d_column_name"=:B1 used at line ID 6 of the execution plan contains an implicit data type conversion on indexed column "d_column_name". This implicit data type conversion prevents the optimizer from selecting indices on table "user_name"."table_name".
Recommendations
Rewrite the predicate into an equivalent form to take advantage of indices.
Rationale
The optimizer is unable to use an index if the predicate is an inequality condition or if there is an expression or an implicit data type conversion on the indexed column.
很明白对吧,谓词"table_name"."d_column_name"=:B1 包含对已加索引的日期列d_column_name上的隐式数据类型转换,导致无法使用索引,于是乎,数据量大了之后,杯具就发生了。。。。。
P.S.(真啰嗦啊)之前的项目用SQL Server数据库,并无此问题。原因是'2012-02-01 00:00:00'这种日期格式,SQL Server可以直接识别,如果日期列上加了索引,则可走索引。
——正式开始之前,先吐吐槽。。。。。
场景描述:系统中查询条件涉及日期的所有操作,都会导致数据库IO开销突增。
-------------------------------------------------------------------------
解决过程:
0.检查日期字段,看其上有无索引,这个是有的
1.拉下来项目代码,配置jrebel,配置log4j,启动项目
2.登录系统,查询,拉取控制台SQL,手动补齐参数值,执行,看执行计划。速度快开销小,木发现有大问题…… 纳闷。。。。。不解。。。。。
3.设置log4j,重启项目,重新执行2:
1)修改
log4j.rootLogger=INFO, stdout
2)新增
log4j.logger.org.hibernate.type=TRACE
log4j.logger.org.hibernate.sql=TRACE
4.查看对日期字段绑定的日期值的类型,竟然是TimeStampType!!!肿么会这样???传进去的值明明是Date类型的。。。。。这样查询不会走索引,而且要把日期列的每个值都转换成时间戳类型再跟传入的值比较。。。。。介个隐式数据类型转换也太神奇了吧
5.将所有类似
hql.append(" and table_name.d_column_name = :d_column_name");
的语句改为
hql.append(" and table_name.d_column_name = cast(:d_column_name as date)");
这样虽然我Trace到的还是TimeStampType,但是在查询里转换成Oracle DATE类型了,就可以走索引了。
问题解决。
-------------------------------------------------------------------------
疑惑:
1.出现这种问题原因是什么?肯定不是日期格式的问题,因为要在页面上设定日期范围的查询,虽然传入字符串并转为短日期格式传入,最后Trace到的还是时间戳类型。不明白,hibernate明明是有DateType的啊。
2.有没有方法可以通过配置hibernate一次性解决这种日期类型转换为时间戳类型的问题?
以上两个疑惑,苦逼DBA问过开发,他们也不知道……
后记:EM中也可以排查到这个问题:Advisor Central>Advisors>Advisor Tasks>Advisory Type = SQL Tuning Advisor > Go > View Result > Overall Task Statistics > Restructure SQL > Select one line> View Recommendations
Type
Restructure SQL
Findings
The predicate "table_name"."d_column_name"=:B1 used at line ID 6 of the execution plan contains an implicit data type conversion on indexed column "d_column_name". This implicit data type conversion prevents the optimizer from selecting indices on table "user_name"."table_name".
Recommendations
Rewrite the predicate into an equivalent form to take advantage of indices.
Rationale
The optimizer is unable to use an index if the predicate is an inequality condition or if there is an expression or an implicit data type conversion on the indexed column.
很明白对吧,谓词"table_name"."d_column_name"=:B1 包含对已加索引的日期列d_column_name上的隐式数据类型转换,导致无法使用索引,于是乎,数据量大了之后,杯具就发生了。。。。。
P.S.(真啰嗦啊)之前的项目用SQL Server数据库,并无此问题。原因是'2012-02-01 00:00:00'这种日期格式,SQL Server可以直接识别,如果日期列上加了索引,则可走索引。
发表评论
-
How-to Install Oracle 12c Database on CentOS 6.X 64bit
2014-04-29 03:21 956http://blog.csdn.net/chncaesar ... -
ORA-12537相关?【转载】查看、修改ORACLE最大进程数
2013-08-28 17:00 1329客户端无法连接数据库,报错ORA-12537,此时登录EM后, ... -
char类型补空格引发的案子
2013-06-17 10:24 1385不多说,都懂的: create table test( c ... -
ORA-28547: 连接服务器失败, 可能是 Oracle Net 管理错误
2013-06-14 15:37 1839问题描述:Navicat 10.0.10 Premium 连 ... -
[转]"ORA-22992: 无法使用从远程表选择的 LOB 定位器"解决方法
2013-06-09 11:06 2537转载自http://blog.csdn.net/weikaif ... -
Oracle通过EM查看具体SQL的执行计划和统计信息
2013-05-27 18:33 1273tableA.columnB上建索引 执行查询 select ... -
windows oracle 11.2.0.1.0 dump blob 到 windows oracle 10.2.0.1.0
2013-05-17 12:02 761source_server expdp src_usr/pwd ... -
[转载]dg v.s. streams v.s. gg
2013-05-06 16:02 777Tom Said: As for setting up the ... -
解决Oracle TEMP临时表空间数据文件过大
2013-05-06 10:11 1690create temporary tablespace tem ... -
产品详情页面加载慢(之前约7s-12s)
2013-04-27 12:03 781问题场景:客户反应网站上的产品详情页面打开时,速度很慢。 运行 ... -
oracle 11.2.0.1 result_cache
2013-04-25 04:27 742alter system set result_cache_m ... -
oracle 重启
2013-04-25 04:23 0重启em emctl stop dbconsole emctl ... -
[转载]ORA-01810: format code appears twice
2013-04-10 17:22 1077遇到报错,ORA-01810: format code app ... -
修改sysman和dbsnmp密码后,EM无法启动
2013-04-10 16:17 2761昨天登陆EM后提示sysman与dbsnmp用户密码过期,在该 ... -
[整理]一行变多行(Oracle)
2013-04-10 10:27 2515来源:http://www.itpub.net/thread- ... -
获取行号
2013-04-10 10:10 828MySQL select @rownum:=@rownum+1 ... -
行转列,列转行
2013-04-09 10:23 849SQL Server http://www.cnblogs.c ... -
多行(结果集)拼接字符串 (多行变一行)
2013-04-09 10:18 1899SQL Server版: select stuff( ... -
ORA-28000: the account is locked
2013-04-02 19:39 902ORA-28000: the account is locke ... -
Oracle11gR2导出数据并导入到10g IMP-00010;ORA-39142
2013-03-25 14:44 2127同事将11.2.0.1的数据导出,导入到10.2.0.1,遇到 ...
相关推荐
类的转换,C++的内部数据类型遵循隐式类型转换规则,成员转换函数
C语言隐式类型转换规则。了解一下对写程序有好处,可以防止不必要的错误
单元十:数据类型的隐式转换-数据类型的隐式转换完整版资料.pptx
JavaScript的数据类型分为六种,分别为null,undefined,boolean,string,number,object。object是引用类型,其它的五种...本章节单独介绍一下javascript中的隐式数据类型转换,对于它的良好掌握,在实际应用能够简化很多
本文将要为您介绍的是Mysql隐式类型转换原则,具体实现方法: MySQL 的隐式类型转换原则: - 两个参数至少有一个是 NULL 时,比较的结果也是 NULL,例外是使用 <=> 对两个 NULL 做比较时会返回 1,这两种...
c编程过程中的数据类型隐式转换,帮助初学者了解数据结构的类型,减少数据类型锁带来的编码错误
C++可以定义如何将其他类型的对象隐式转换为我们的类类型或将我们的类类型的对象隐式转换为其他类型。为了定义到类类型的隐式转换,需要定义合适的构造函数。 说明:可以用单个实参来调用的构造函数定义了从形参...
该文档描述了oracle数据的转换的一些规则,如字符和数字的转换,字符和日期的转换
一、从 数字类型 转换成 字符串类型A、 显式转换console.log(typeof numberA) // numberB、 隐式转换console.log
nvarchar binary数据类型转换
本文实例讲述了JavaScript强制类型转换和隐式类型转换。分享给大家供大家参考,具体如下: 在JavaScript中声明变量不需指定类型, 对变量赋值也没有类型检查,同时JavaScript允许隐式类型转换。这些特征说明...
JavaScript隐式类型转换_.docx
相信大家都知道隐式类型转换有无法命中索引的风险,在高并发、大数据量的情况下,命不中索引带来的后果非常严重。将数据库拖死,继而整个系统崩溃,对于大规模系统损失惨重。所以下面通过本文来好好学习下MySQL隐式...
在js中,数据类型转换分为显式数据类型转换和隐式数据类型转换。 1, 显式数据类型转换 a:转数字: 1)Number转换: 代码: var a = “123”; a = Number(a); 注意: a) 如果转换的内容本身就是一个数值类型的字符...
隐式型、弱类型转换:+ - * / (运算符) undefined 转数字:NaN null 转成数字:0 true 转数字:1 false 转成数字:0 数字除以0结果是infinity 例:var a = 'null'; var b = '5'; console.log( b / a); ...
主要介绍了c++隐式类型转换的二个示例,需要的朋友可以参考下
主要介绍了JS面试题大坑之隐式类型转换实例代码,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下