I am dealing with what is apparently a performance issue while retrieving a relatively large ResultSet
from a remote Microsoft SQL Server 2012 to a Java client that uses Microsoft JDBC Driver 4.0.
When I run the corresponding query on the remote server's Microsoft SQL Server Management Studio, it returns approx. 220k rows almost instantaneously. When I issue the same query from the client, it stalls. The same test has worked fine also on the client with an earlier version of the database where only approx. 400 rows qualified.
I tried to tackle this by appending ;responseBuffering=adaptive"
to the URL passed to DriverManager.getConnection()
. After the connection is established, I see this property (among several others) in the result from connection.getMetaData().getURL()
, but[ connection.getClientInfo(responseBuffering)
returns null
, and what is more the client is still stalling.
What could be going wrong here and how can I instruct the a Microsoft SQL Server (not just suggest to it -- programmatically in Java) that it must return rows in smaller chunks rather than all at once or improve JDBC query times by some other measures.
Two further observations that seem somewhat strange and that perhaps point to a different root cause entirely:
- When the client stalls it still shows only relatively light CPU load, unlike what I would expect from heavy garbage collection
- "responseBuffering=adaptive" should be the normal default by now
UPDATE I've checked and found that switching from PreparedStatement
to Statement
does not improve things in my case (it apparently can help in other cases).
UPDATE Here is my current query:
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