`

万恶的隐式数据类型转换

阅读更多
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可以直接识别,如果日期列上加了索引,则可走索引。
分享到:
评论

相关推荐

    C语言隐式类型转换规则

    2. **运算符两边的数据类型转换**:当运算符两边的数据类型不一致时,较低级别的类型会被转换为较高级别的类型。 - 例如,`int + double` 的运算中,`int` 会被转换为 `double` 类型。 3. **赋值过程中的类型转换**...

    单元十:数据类型的隐式转换-数据类型的隐式转换完整版资料.pptx

    数据类型的隐式转换是计算机编程中一个重要的概念,它指的是在编程语言中,编译器或解释器自动将一种数据类型转换为另一种数据类型的过程。这种转换可以是隐式的,也可以是显式的。数据类型的隐式转换在编程中非常...

    类的转换C++的内部数据类型遵循隐式类型转换规则

    这种转换通常分为两种类型:转换构造函数和成员转换函数,这两种方法都遵循C++的隐式类型转换规则。 首先,转换构造函数是一种特殊的构造函数,它的作用是将非本类类型的对象转换成本类的对象。在给定的代码示例中...

    隐式类型转换

    隐式类型转换是C语言中的一种重要概念,它指的是在编译时由编译程序按照一定规则自动完成的数据类型转换。这种转换在C语言的表达式中经常出现,当不同类型的数据参与同一运算时,编译器就会按照规定的规则将其转换为...

    C++类各种类型转换_数据类型的相互转换_

    总的来说,C++的数据类型转换是一门深奥的学问,熟练掌握各种转换方法是成为一名合格的C++程序员的关键。在编写程序时,应始终注意类型安全,避免不必要的类型转换,特别是那些可能导致数据丢失或错误的转换。通过...

    简单介绍JavaScript数据类型之隐式类型转换

    JavaScript的数据类型分为六种,分别为null,undefined,boolean,string,number,object。object是引用类型,其它的五种...本章节单独介绍一下javascript中的隐式数据类型转换,对于它的良好掌握,在实际应用能够简化很多

    数据类型转换

    ### 数据类型转换详解 在计算机科学领域,尤其是在嵌入式系统开发中,数据类型转换是一项基本而重要的技术。本文将围绕“数据类型转换”这一主题展开深入探讨,并结合STM32平台的应用背景进行分析。 #### 标题:...

    TypeByte@2019_C#_C++_C数据类型转换时间戳转换_

    1. C#的数据类型转换:显式与隐式转换,DateTime结构与Unix时间戳的相互转换。 2. C++的数据类型转换:static_cast、dynamic_cast、C-style cast和const_cast,以及时间戳的自定义处理。 3. C语言的数据类型转换和...

    day02 【数据类型转换、运算符、方法入门】.zip

    在Java这样的强类型语言中,了解并熟练掌握数据类型转换、运算符和方法是成为一名合格的程序员的必经之路。在这个"day02 【数据类型转换、运算符、方法入门】"的学习资料中,我们将深入探讨这些关键概念。 首先,...

    C#数据类型转换问题集锦

    C# 数据类型转换问题集锦 C# 数据类型转换是一个非常重要的概念,掌握好数据类型转换对于编程开发非常重要。本文将会对 C# 中的数据类型转换进行总结和分析,并提供了一些实用的代码示例。 在 C# 中,数据类型可以...

    nvarchar binary数据类型转换

    因此,在进行数据类型转换时,必须清楚了解数据的内容和预期的用途,以避免不必要的数据丢失或错误。 在SQL Server 2008 R2中,`nvarchar`与`binary`之间的转换是一个常见的操作,特别是在处理用户输入、存储过程、...

    Oracle数据隐式转换规则

    规则 5: 当调用函数或过程等时,如果输入参数的数据类型与函数或者过程定义的参数数据类型不一致,则 Oracle 会将输入参数的数据类型转换为函数或者过程定义的数据类型。例如,假设过程如下定义 p(p_1 number)exec p...

    java 数据类型转换

    本文将深入探讨Java中的数据类型转换,包括自动类型转换(隐式转换)和强制类型转换(显式转换)。 ### 自动类型转换(隐式转换) 当一个数据类型转换为另一个兼容的、范围更大的数据类型时,Java会自动执行这种...

    oracle数据隐式转换规则

    该文档描述了oracle数据的转换的一些规则,如字符和数字的转换,字符和日期的转换

    JS 数据类型转换

    JavaScript中的数据类型转换主要分为两类:隐式转换和显式转换。 **隐式转换**常常发生在操作符、比较运算以及函数调用等场景。例如,将字符串与数字相加会尝试将字符串转换为数字;在条件语句中,非布尔值会被转换...

    C++ 多种数据类型转换

    本篇文章将深入探讨C++中的数据类型转换,包括隐式转换和显式转换,并通过实例来解释它们的用法。 ### 隐式类型转换(Automatic Type Conversion) 隐式类型转换是指在某些操作或赋值过程中,编译器自动进行的数据...

    C语言中强制数据类型转换的总结

    在C语言中,数据类型转换可以分为隐式转换和显式转换。隐式转换是系统自动进行的,不需要程序员干预;显式转换是程序员通过强制类型转换运算符来实现的。 在数据类型转换中,需要注意的是低类型到高类型的转换和高...

    SQL Server 中的数据类型隐式转换问题

    在SQL Server中,数据类型隐式转换是一种自动将一种数据类型转换为另一种数据类型的过程,通常发生在不同数据类型的值进行操作或比较时。虽然这种转换能够简化编程,但如果不了解其工作原理,可能会引发意料之外的...

    javascript最常用数据类型转换(最全).doc

    JavaScript 数据类型转换详解 JavaScript 中有多种数据类型,包括数值类型、字符串类型、布尔类型等。这些类型之间可以进行转换,以下是 JavaScript 中最常用的数据类型转换方法。 一、转为字符串 在 JavaScript ...

    数据类型转换的整理,

    在编程领域,数据类型转换是不可或缺的一个环节,尤其是在C语言和C++这两种广泛使用的编程语言中。数据类型转换涉及到将一个数据类型的数据转化为另一种数据类型,以满足特定的计算或存储需求。本篇文章将深入探讨...

Global site tag (gtag.js) - Google Analytics