oracle Hibernate执行JDBC语句的速度慢得多

ubby3x7f  于 2023-10-16  发布在  Oracle
关注(0)|答案(1)|浏览(180)

TL;DR相同的SQL查询,当在休眠状态下执行时,需要70秒以上,当使用sql developer执行时,只需1.5秒
我发现,当一个特定的查询由hibernate执行时,它所花费的时间要比我在sql客户端中运行生成的sql要长得多。例如,在启用休眠静态后,我可以在日志中看到

  • 执行2条JDBC语句花费67839913762纳秒 *;相当于1.13分钟

但是,如果我使用生成的SQL并运行它,它最多只需要1.5秒
谁能告诉我造成这种差异的可能原因是什么?我的理解是,执行JDBC语句的时间完全取决于DB,对吗?如果SQL是相同的,为什么它在休眠时执行得这么慢?
单一实体类

@Entity
@Data
@AllArgsConstructor
@Builder
public class GpCustomer {
  @Id
  @Column(name = "CUSTNO")
  private String custno;

  @Column(name = "COMPANY")
  private String company;
}

示例库

@Repository
public interface GpCustomerRepository extends JpaRepository<GpCustomer, String> {}

示例服务

public Page<GpCustomer> findAllCustomers() {
    Pageable limit = PageRequest.of(0,10);
    return GpCustomerRepository.findAll(limit);
  }

更新:hibernate统计数据

Session Metrics {
    137214920 nanoseconds spent acquiring 1 JDBC connections;
    0 nanoseconds spent releasing 0 JDBC connections;
    18734658 nanoseconds spent preparing 2 JDBC statements;
    67839913762 nanoseconds spent executing 2 JDBC statements;
    0 nanoseconds spent executing 0 JDBC batches;
    0 nanoseconds spent performing 0 L2C puts;
    0 nanoseconds spent performing 0 L2C hits;
    0 nanoseconds spent performing 0 L2C misses;
    0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
    16386 nanoseconds spent executing 2 partial-flushes (flushing a total of 0 entities and 0 collections)
}
f1tvaqid

f1tvaqid1#

这种行为的一个可能原因是Hibernate实际上获取所有数据,而SQL客户端可能只获取几行。像Hibernate那样实现所有行显然需要更长的时间。
另一个可能的原因是,优化器对待SQL客户端最有可能执行的“文学SQL”的方式不同,并且比Hibernate使用的参数化版本执行得更好。Hibernate使用带参数标记的PreparedStatement,因此这样的语句更加通用,优化器在规划查询时可能会对其估计感到悲观。一个“识字的SQL”,即没有参数标记就没有这个问题。优化器将为该SQL创建一个专门的查询计划。
为了做一个公平的比较并排除这些缺陷,编写一个JDBC程序,使用PreparedStatement和参数标记来读取所有数据,即通过ResultSet到达终点。然后您可以比较运行时。
如果您受到第二个选项的影响,请与您的DB管理员讨论此问题。我知道Oracle在优化过程中有一些选项可以查看参数值,所以这可能会有所帮助。

相关问题