【问题标题】:Is it possible to disable jpa hints per particular query?是否可以为每个特定查询禁用 jpa 提示?
【发布时间】:2016-08-18 20:32:45
【问题描述】:

JPA,在我的特殊情况下是 eclipselink,在使用 query.setFirstResult()/query.setMaxResults() 的情况下生成 /*+ FIRST_ROWS */

SELECT * FROM (
  SELECT /*+ FIRST_ROWS */ a.*, ROWNUM rnum  FROM (
    SELECT * FROM TABLES INCLUDING JOINS, ORDERING, etc.) a
  WHERE ROWNUM <= 10 )
WHERE rnum > 0;

这迫使 Oracle 使用嵌套循环而不是哈希连接。一般来说,有降神会,但在我的特殊情况下,它会大大降低性能。

是否可以禁用特定查询的提示使用/生成?

【问题讨论】:

  • 为什么需要使用 setFirstResult?
  • 解释没有 /* + FIRST_ROWS*/ 的计划真的更好吗?
  • 嵌套循环并不是一件很糟糕的事情,当你只有几千行时,HASH join也不是一个很好的选择
  • AFAIK Eclipselink 有类似 setHint 的方法。如果您使用 Hibernate,您应该联系 Hibernate 支持。 eclipse.org/eclipselink/documentation/2.4/jpa/extensions/…
  • @Thomas setFirstResult 用于分页。我同意通常嵌套循环可能比散列连接更好。我相信这就是重点,为什么 oracle 会根据我的要求选择它。

标签: java oracle jpa oracle11g


【解决方案1】:

正如@ibre5041 所说,FIRST_ROWS 提示已被弃用,在 Oracle 的上下文中,应使用 FIRST_ROWS(N) 代替它。在我的情况下,FIRST_ROW 和 FIRST_ROW(N) 实际上都不需要,所以为了告诉 eclipselink 不要使用过时的东西,可以在 persistence.xml 中指定 oracle 版本:

<property name="eclipselink.target-database" value="org.eclipse.persistence.platform.database.oracle.Oracle11Platform" />

添加后,我得到了奇怪的错误: Could not initialize class org.eclipse.persistence.platform.database.oracle.Oracle11Platform 但是,在我将 ojdbcN.jar 放入 domain/lib/ext 后,错误就消失了。

因此,eclipselink 生成没有 FIRST_ROW 提示的查询,Oracle 使用更好的计划。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多