【问题标题】:How find the query difference between hibernate and running sql directly?如何找到hibernate和直接运行sql的查询区别?
【发布时间】:2013-01-08 12:54:18
【问题描述】:

我有这样的查询:

 delete from tableA where fk in (select id from tableA where fk='somevalue'
 and tableA.date between date1 and date2)

当我从 TOAD 运行此查询时,它需要将近 100 毫秒。当我使用

                   session
                .createSQLQuery(
                        "delete ....")
                .setParameter("...")
                .setParameter("...")
                .setParameter("...")
                .executeUpdate();

大约需要 30 分钟 真正的查询删除了 0 行。所以可能存在一些休眠/oracle问题。我怎样才能找到它们? 谢谢。

【问题讨论】:

  • 不明白。请详细说明。条件需要子查询 - 应该删除哪些行。它会产生问题吗?
  • 我建议按照herehere 的说明启用Hibernate 的查询日志,因为在运行本机查询时不应该有这样的差异。
  • 通过 show sql 属性获取 SQL 并在其上运行解释计划。这将为优化提供一些线索。顺便说一句,上面的查询看起来很奇怪,您不需要“IN”子句...猜那是因为您简化了说明...
  • tableA 是子查询中的错字吗?还是您真的要查询同一张表两次?

标签: java oracle hibernate time


【解决方案1】:

您可能在谈论hibernate.show_sql property from Hibernate configurations(ctrl+f for "show_sql")

将此属性设置为“true”会将使用的 SQL 打印到标准输出

【讨论】:

  • 谢谢。我已将 show_sql 设置为 true。这与我假设的查询相同。但它挂起的原因不明。我不明白为什么......
【解决方案2】:

在这么长时间的情况下,hibernate可能产生的小开销不会被注意到。

您可以通过在fkdate 列中添加索引来加快删除速度(在这种情况下复合索引可能会很好)。

更新 我会详细说明一下,以澄清我为什么建议这样做。 Hibernate 必须为执行的查询解析映射(并且在 select 语句的情况下,它必须创建对象并用结果填充它们)。在这种情况下,这个开销看起来并不重要,因为我们谈论的是 30 分钟的执行时间。

所以问题可能出在其他地方,例如:

  • 如果从不同的机器执行 TOAD 和 java 进程会出现网络问题
  • JDBC 和 OCI 之间的一些区别
  • 查询翻译错误,可以使用 show_sql 属性检查。在这种情况下,通常映射有问题。

由于没有问题中所述的任何删除,即使查询需要 30 分钟,这就是我建议索引的原因。确实它可能会减慢删除速度,但同样,在这种情况下不会删除任何行,因此执行子查询需要 30 分钟,而不是执行任何删除操作。

这个答案可能无法解决问题,但老实说,我认为它不值得投反对票。

【讨论】:

  • 正如问题中所解释的,当在工具中执行时,他的查询已经非常快了。添加索引甚至可能会减慢删除速度,因为它们还必须在删除时进行更新。
  • 但是这个问题可能不会是休眠的,因为它与这样的查询几乎没有关系。也许那么 jdbc 和 OCI 之间的区别,如果从不同的盒子执行,网络问题....我想说的是,休眠可能不是原因。
猜你喜欢
  • 2018-07-09
  • 1970-01-01
  • 1970-01-01
  • 2020-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-03
  • 2017-12-07
相关资源
最近更新 更多