Dru*_*rux 9 java sql-server jdbc sql-server-2012
我正在处理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查询时间.
两个进一步的观察似乎有点奇怪,可能完全指向不同的根本原因:
更新我已经检查过,发现在我的情况下切换PreparedStatement到Statement没有改善的东西(显然在其他情况下可以帮助).
更新这是我当前的查询:
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
OBJECTS as CHILD
left outer join RELATIONS on RELATIONS.CHILD = CHILD.IDENTIFIER
left outer join OBJECTS as PARENT on RELATIONS.PARENT = PARENT.IDENTIFIER
inner join PROPERTIES as PROPERTY on PROPERTY.OBJECT = CHILD.IDENTIFIER
where
PROPERTY.TARGET is not null
order by
case when PARENT.IDENTIFIER is null then 1 else 0 end,
PARENT.IDENTIFIER,
CHILD.IDENTIFIER,
PROPERTY.TARGET,
PROPERTY.IDENTIFIER
Run Code Online (Sandbox Code Playgroud)
自适应缓冲是一个很好的答案。SET我还建议通过 SQL Server Profiler检查连接选项。
当您开始跟踪时,请确保ExistingConnections选中。比较来自 JDBC 连接和 SSMS 连接的 SPID。 ARITHABORT我想到的是,我发现它导致了 SSMS 和 JDBC 驱动程序之间的性能差异。微软在这里简要提到了它:http://msdn.microsoft.com/en-us/library/ms190306.aspx。此处的堆栈交换信息:https://dba.stackexchange.com/questions/9840/why-would-set-arithabort-on-dramatically-speed-up-a-query
在 Oracle 上,我通过使用/对象setFetchSize上的方法看到了巨大的影响。显然,SQL Server 驱动程序不支持该方法。但是,驱动程序中有一个内部方法可以实现这一点。有关详细信息,请参阅使用 JDBC 驱动程序在 SQL Server 中设置默认行预取。StatementPreparedStatement
另外,你在循环中做什么while (rs.next())?尝试除了阅读专栏之外什么也不做,例如rs.getInt(1)。走着瞧吧。如果成功,则表明瓶颈在于您之前对结果集的处理。如果仍然很慢,那么问题一定出在驱动程序或数据库上。
您可以使用 SQL Server Profiler 来比较通过 JDBC 传入的执行和通过 SSMS 运行的执行。比较 CPU、读取、写入和持续时间。如果它们不同,那么执行计划可能会不同,这让我回到了我提到的第一件事:选项SET。