1

我们正在测试来自 jTDS 和 Microsoft 的 JDBC 驱动程序,并且我们在查询执行中遇到了不必要的暂停。我们的应用程序打开了许多 ResultSets 并从每个 ResultSets 中只获取几行。每个查询选择大约 100k 行,但我们只获取大约 50 行(这足以填满一页)。问题是第一个查询之后的每个查询都包含大约 2 秒的暂停,在此期间驱动程序将前一个 ResultSet 中的所有行加载到临时存储(内存或磁盘)中,因此可以稍后遍历它们。因为我们在最坏的情况下大约有 6 次查询,所以会有大约 10s 的暂停,这使得应用程序对用户没有响应。MSSQL 版本是 2005。

为了消除这种暂停,我们尝试通过 Microsoft JDBC 驱动程序的连接字符串参数启用 MARS(多个活动结果集)(由于缺乏文档,我们尝试了https://sites.google.com/上列出的所有内容站点/sqlconnect/sql2005strings)。连接字符串示例:

jdbc:sqlserver://TESTDBMACHINE;instanceName=S2005;databaseName=SampleDB;MarsConn=yes

但他们都没有解决问题。Microsoft JDBC 驱动程序似乎接受连接字符串中的任何内容 - 如果您将 MarsConn=yes 替换为 PleaseBeFast=yes,MS 驱动程序将忽略该参数并且甚至不记录该事实。我不知道 MARS 是仅用于缓存先前活动结果集中的行的客户端功能,还是服务器功能。我什至不知道如何从服务器端检测给定的连接是否正在使用 MARS。如果您可以对此发表评论,将受到欢迎。

暂停的另一个解决方案是使用可滚动(双向)结果集。这消除了暂停,但使获取时间变慢了 80% 并且更多的网络消耗。我们现在正在考虑实现一个 JDBC 连接包装器,它保留一个实际连接池并自动向不同的“ResultSet free”连接发出查询。但这有点麻烦,因为我们需要在每个连接与其活动的 ResultSet 之间保持链接。此外,它会消耗来自服务器的更多连接,并可能给 DBA 带来麻烦。如果存在活动事务,则此解决方案无济于事,所有查询都必须在同一连接上发出。

您是否知道一些参数、配置、特定 API、链接或技巧可以消除第二次和后续查询执行的暂停?

4

3 回答 3

1

修复您的 SQL 查询! 为什么只使用 100k 行中的前 50 个左右?使用TOP 100或类似的东西!应用程序没有理由过滤 100k 行,这是数据库的工作。

于 2011-09-01T14:37:43.150 回答
0

更重要的是,您的客户端遇到的问题是服务器端发生的事情。由于您发出查询然后停止读取结果,因此服务器将不得不在执行过程中暂停查询,因为网络缓冲区已满并且没有空间将结果写入。在执行过程中暂停的查询会消耗大量资源:内存、锁以及最重要的工作线程(这些资源很少

仅针对您需要的数据发出查询,使用所有数据,释放连接,更重要的是释放服务器资源。如果您的查询过于复杂,请返回绘图板并重新设计您的数据模型,以正确、有效地回答您从中请求的查询。现在你完全是在找错树,你只是在问如何让糟糕的情况变得更糟。

于 2011-09-01T19:10:01.017 回答
-1

我们使用 SQL Server 驱动程序 (Native Client 10 - sqlncli10.dll) 创建了一个 ODBC 数据源。此 ODBC 数据源已配置为启用 MARS(键、值必须为)。然后我们使用了 Sun 的 JDBC-ODBC 桥,瞧!停顿消失了,令人惊讶的是,获取时间变得比 JTDS 和 MSSQL 纯 Java JDBC 驱动程序更快!HKEY_CURRENT_USER\Software\ODBC\ODBC.INI\ datasourceMARS_ConnectionYes

根据http://msdn.microsoft.com/en-us/library/ms345109(SQL.90).aspx,MARS 是一个服务器辅助功能。纯 Java 驱动程序(来自 JTDS 和 MSSQL)似乎不支持基于服务的 MARS(至少在多次配置更改后我们无法启用它)。因为我们使用 MSSQL Server 的大多数用户群都在 Windows 上运行(不足为奇),所以我们即将从 JTDS 切换到 JDBC-ODBC。Native Client ODBC 驱动程序和 JDBC-ODBC 桥接器似乎都是成熟的、功能齐全的和最新的解决方案,所以我想应该没有问题。如果你知道一些,请评论!

基于 Linux 的用户仍将使用 JTDS。既然现在我们知道 MARS 是一个服务器辅助功能,我们将为 JTDS 和 Microsoft 填写一个功能请求,以在其纯 Java JDBC 驱动程序中支持 MARS。

于 2011-09-16T12:03:18.597 回答