相关疑难解决方法(0)

为什么参数化查询会产生比非参数化查询慢得多的查询计划

在SQL Server 2005数据库中,我正在处理此查询:

select*
from foo
join bar on bar.x = foo.x
join baz on baz.y = foo.y
where foo.x = 1000

与以下参数化版本相比,它具有非常不同且更快的查询计划.

声明@p0 int
set @ p0 = 1000
select*
from foo
join bar on bar.x = foo.x
join baz on baz.y = foo.y
where foo.x = @ p0

在我的特定情况下,具有文字的版本在亚秒时间运行.参数化版本需要2-3秒.我认为它们是相同的,因为它们是相同的查询.

为什么他们会得到不同的查询计划?

有没有办法让参数化版本具有与文字版本相同的性能?

这是查询计划.我的真实查询与上面给出的通用查询有很大不同,但产生这些计划的两个查询之间的唯一区别是参数.为什么用一个参数替换一个文字会产生如此大不相同的计划?

sql-server

22
推荐指数
3
解决办法
8415
查看次数

为什么Microsoft SQL Server 2012查询需要几分钟而不是JDBC 4.0,而在Management Studio中需要几分钟?

我正在处理ResultSet从远程Microsoft SQL Server 2012到使用Microsoft JDBC Driver 4.0的Java客户端检索相对较大的性能问题.

当我在远程服务器的Microsoft SQL Server Management Studio上运行相应的查询时,它返回约.220k行几乎瞬间完成.当我从客户端发出相同的查询时,它会停止.同样的测试在客户端上运行良好,早期版本的数据库只有大约.400行合格.

我尝试通过附加;responseBuffering=adaptive"到传递给的URL 来解决这个问题DriverManager.getConnection().建立连接后,我在结果中看到了这个属性(以及其他几个)connection.getMetaData().getURL(),但是[ connection.getClientInfo(responseBuffering)返回null,而且客户端仍然停滞不前.

这里可能出现什么问题,如何指示Microsoft SQL Server(不仅仅是以Java编程方式建议)它必须以较小的块而不是一次性返回行,或者通过其他一些措施来改进JDBC查询时间.

两个进一步的观察似乎有点奇怪,可能完全指向不同的根本原因:

  • 当客户端停止时,它仍然只显示相对较轻的CPU负载,这与我对重垃圾收集的期望不同
  • "responseBuffering =自适应"应在正常默认由现在

更新我已经检查过,发现在我的情况下切换PreparedStatementStatement没有改善的东西(显然在其他情况下可以帮助).

更新这是我当前的查询:

select 
    PARENT.IDENTIFIER    as PARENT_IDENTIFIER,
    PARENT.CLASS         as PARENT_CLASS,
    CHILD.TYPE           as CHILD_TYPE,
    CHILD.IDENTIFIER     as CHILD_IDENTIFIER,
    PROPERTY.IDENTIFIER  as PROPERTY_IDENTIFIER,
    PROPERTY.DESCRIPTION as PROPERTY_DESCRIPTION,
    PROPERTY.TYPE        as PROPERTY_TYPE,
    PROPERTY.PP          as PROPERTY_PP,
    PROPERTY.STATUS      as PROPERTY_STATUS,
    PROPERTY.TARGET      as PROPERTY_TARGET -- a date
from …
Run Code Online (Sandbox Code Playgroud)

java sql-server jdbc sql-server-2012

9
推荐指数
1
解决办法
7474
查看次数

Hibernate比SQL查询慢1000倍

我有这个设置

@Table(name ="A")
EntityA {
    Long ID;
    List<EntityB> children;
}

@Table(name ="B")
EntityB {
    Long ID;
    EntityA parent;
    EntityC grandchild;
}

@Table(name ="C")
EntityC {
    Long ID;
}
Run Code Online (Sandbox Code Playgroud)

SQL查询是这样的(我省略了无关的细节):

select top 300 from A where ... and ID in (select parent from B where ... and grandchild in (select ID from C where ...)) order by ...
Run Code Online (Sandbox Code Playgroud)

直接数据库中或通过Hibernate(3.5)SQL进行的SQL查询比使用Criteria或HQL表示此查询的运行速度快1000。

生成的SQL HQL和Criteria以及我在此处发布的SQL 相同

[编辑]:更正-sql不同。我没有在管理工作室方面尝试过Hibernate样式参数设置,因为直到后来我才意识到这一点-请参阅我的答案。

如果我将子查询分成单独的查询,那么它又很快。

我试过了

  • 删除子项,父项等的所有映射,并仅使用Long ID引用-同一件事,因此与获取,懒惰和渴望无关。
  • 使用联接而不是子查询,并且在所有访存和加载组合下都表现出相同的缓慢行为。
  • 在ID上设置投影而不是检索实体,因此没有对象转换-仍然很慢

我看了一下Hibernate代码,它的功能令人震惊。它遍历所有300个结果,最终到达数据库。

private List doQuery(
        final SessionImplementor session,
        final QueryParameters queryParameters, …
Run Code Online (Sandbox Code Playgroud)

java sql database performance hibernate

6
推荐指数
2
解决办法
9059
查看次数