【问题标题】:MSSQL, SP_EXECUTESQL and javax.persistence.EntityManagerMSSQL、SP_EXECUTESQL 和 javax.persistence.EntityManager
【发布时间】:2017-12-08 19:38:27
【问题描述】:

拥有一个从 Oracle 迁移到 SQL Server 2016 的 JavaEE 应用程序。 使用 Java 1.7、jboss 4.2.3.GA 和休眠 3.2.4.sp1。

应用程序使用 javax EntityManager 进行 DB 访问,因此查询如下所示:

    List<ServiceProvider> providers = entityManager
            .createQuery("FROM ServiceProvider sp order by sp.id")
            .setMaxResults(spCount)
            .getResultList();

但是 SQL 跟踪显示查询被包裹在 exec sp_executesql 中。

例如上面变成exec sp_executesql N'SELECT TOP (50) ....'

如果我跟踪来自 SSRS 报告的查询,它不会包含在 sp_executesql 中。

造成这种转变的原因是什么?

** 编辑为一个重点问题。

【问题讨论】:

  • 这就是 Microsoft SQL Server JDBC 驱动程序的工作原理。如果你想知道细节,我建议你问微软,例如github.com/Microsoft/mssql-jdbc
  • @MarkRotteveel 它似乎是休眠状态,如果我通过 jMeter 使用相同的驱动程序运行相同的查询,它不会被包裹在 sp_executesql 中。
  • 这可能是执行“正常”语句和准备好的语句之间的区别。
  • @MarkRotteveel 毫无疑问。无论如何,jMeter 向我展示了使用和不使用 sp_executesql 时的更好性能,因此请查看 hibernate 配置。

标签: java sql-server hibernate jdbc


【解决方案1】:

正如@MarkRotteveel 在他的评论中提到的,MS JDBC 驱动程序在执行准备好的语句时似乎使用了sp_executesql。一旦我们修复了缺失的pool-sizeprepared-statement-cache-size 选项,我们发现Oracle 12g 和SQL Server 2016 之间没有区别,所以我认为使用sp_executesql 不会影响性能,或者如果存在,它就是非常极少。

    <min-pool-size>20</min-pool-size>
    <max-pool-size>220</max-pool-size>
    <prepared-statement-cache-size>100</prepared-statement-cache-size>

有趣的是,Hibernate 在针对 MSSQL 时执行的查询比 Oracle 少。我原始帖子中的查询产生了 12 个 Oracle 查询,而 MSSQL 中产生了 10 个。

【讨论】:

  • 如果有人有更多关于 mssql-jdbc 驱动程序使用 sp_executesql 的信息,我很乐意切换接受的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-28
  • 2012-07-17
  • 1970-01-01
  • 2013-01-22
  • 1970-01-01
  • 2012-06-15
  • 1970-01-01
相关资源
最近更新 更多