【问题标题】:Hibernate 5 Native query support - Slow response generationHibernate 5 本机查询支持 - 响应速度慢
【发布时间】:2019-06-15 01:33:21
【问题描述】:

我正在尝试使用 Hibernate createNativeQuery 获取 1000 行。该查询包含两个连接。当我在 SQL 开发人员中执行相同操作时,我看到响应在不到 400 毫秒内出现,但从代码中需要 20 秒才能得到结果。

表格

员工 - id、姓名、country_id、dept_id

国家 - id、country_name、office_count、inflation_rate

部门 - id、部门名称、经理

String queryStr = "Select e.id as id, e.name as empName, c.country_name AS countryName,
    d.dept_name AS deptName FROM  owner.Employee AS e LEFT OUTER JOIN owner.Country c
        ON e.country_id = c.id LEFT OUTER JOIN owner.Dept AS d ON e.country_id = d.id";

List<Object[]> rows  = this.getSession().createNativeQuery(queryStr).setMaxResults(1000)
    .addScalar( "id", StringType.INSTANCE )
    .addScalar( "empName", StringType.INSTANCE )
    .addScalar( "countryName", StringType.INSTANCE )
    .addScalar( "deptName", StringType.INSTANCE )
    .list();

Hibernate 正在执行的可能导致此延迟的附加处理是什么?有什么办法可以优化代码吗?

【问题讨论】:

  • 在 SQL Developer 中执行时,IDE 是返回所有行还是只返回前 N 行?如果 IDE 未检索所有行,则比较可能不公平。
  • 您的数据表明以下解释。要获取前 20 行(一页数据),经过的时间是 400 毫秒。线性缩放以获得所有 1000 行需要 20 秒。顺便说一句。您在查询中需要 2 到 3 千次索引访问 - 如果索引块在磁盘上,您每秒可以获得大约 100 次磁盘访问,这接近您 20 秒的观察时间。

标签: oracle hibernate query-optimization jave


【解决方案1】:

我在您的 Hibernate 代码中没有看到任何单独的内容可以解释异常缓慢的性能。对addScalar() 的调用可能会稍微减慢速度,但这应该是次要的。

如果您想显着加快查询速度,则需要考虑调优和优化。这是一种应该有帮助的索引策略:

CREATE INDEX country_idx ON Country (id, country_name);
CREATE INDEX dept_idx ON Dept (id, dept_name);

此策略假定 Oracle 将对Employee 表进行全表扫描。然后,上述两个索引将允许对连接中涉及的每条记录进行快速查找。

【讨论】:

  • 即使没有索引,当我从 SQL 开发人员运行它时,查询也非常快。根据休眠文档。 “为了避免使用 ResultSetMetadata 的开销,或者只是为了更明确地返回返回的内容,可以使用 addScalar():”
  • 直接对数据库运行查询和从 Java 代码运行它不是一回事。后一种情况意味着您可能必须通过网络发送大量数据。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-30
  • 2017-06-05
  • 1970-01-01
  • 2018-04-05
相关资源
最近更新 更多