与非常繁忙的 SQL 2000 的 JDBC 连接:selectMethod=光标 vs selectMethod=直接?
-
26-09-2019 - |
题
在尝试帮助应用程序开发团队解决 SQL 2000 服务器上的性能问题(来自不同应用程序服务器上的一堆 Java 应用程序)的过程中,我运行了 SQL 跟踪,发现对数据库的所有调用都充满了 API服务器游标语句(sp_cursorprepexec、sp_cursorfetch、sp_cursorclose)。
看起来他们正在指定一些连接字符串属性,强制使用服务器端游标,一次仅检索 128 行数据:(从 http://msdn.microsoft.com/en-us/library/Aa172588)
当API光标属性或属性设置为默认值以外的任何内容时,SQL Server的OLE DB提供程序和SQL Server ODBC驱动程序使用API Server Cursors而不是默认结果集。每个调用API函数获取行都会生成往返服务器的往返,以从API服务器光标中获取行。
更新:有问题的连接字符串是 JDBC 连接字符串参数, selectMethod=cursor
(这启用了我们上面讨论的服务器端游标)与替代方案 selectMethod=direct
. 。他们一直在使用 selectMethod=cursor
作为所有应用程序的标准连接字符串。
从我的 DBA 角度来看,这很烦人(它用无用的垃圾扰乱了跟踪),并且(我推测)会导致许多额外的应用程序到 SQL 服务器的往返,从而降低整体性能。
他们显然做了测试更改(只是大约 60 个不同的应用程序连接之一) selectMethod=direct
但遇到了一些问题(我没有详细信息)并且担心应用程序崩溃。
所以,我的问题是:
- 可以使用
selectMethod=cursor
正如我试图争辩的那样,应用程序性能较低?(通过增加每秒查询量已经非常高的 SQL 服务器上所需的往返次数) - 是
selectMethod=
JDBC 连接上的应用程序透明设置?如果我们更改它,这会破坏他们的应用程序吗? - 更一般地说,什么时候应该使用
cursor
与direct
?
还 交叉发布到 SF.
编辑:收到了需要对标题、问题和标签进行重大编辑的实际技术细节。
编辑:添加了赏金。还为 SF 问题添加了赏金(该问题侧重于应用程序行为,SF 问题侧重于 SQL 性能。)谢谢!
解决方案
简要地,
selectMethod=cursor
- 理论上需要 更多服务器端资源 比
selectMethod=direct
- 最多只加载 批量大小 立即记录到客户端内存中,从而产生更可预测的客户端内存占用
- 理论上需要 更多服务器端资源 比
selectMethod=direct
- 理论上需要的服务器端资源比
selectMethod=cursor
- 在客户端应用程序对其进行迭代之前,会将整个结果集读入客户端内存(除非驱动程序本身支持异步结果集检索);这 可以通过两种方式降低性能:
- 如果客户端应用程序的编写方式是在仅遍历结果集的一小部分后停止处理(使用
direct
它已经支付了检索基本上会丢弃的数据的成本;和cursor
废物最多限于 批量大小 - 1 行——无论如何,提前终止条件可能应该用 SQL 重新编码,例如作为SELECT TOP
或窗口函数) - 由于与内存占用增加相关的潜在垃圾收集和/或内存不足问题,大型结果集的性能降低
- 如果客户端应用程序的编写方式是在仅遍历结果集的一小部分后停止处理(使用
- 理论上需要的服务器端资源比
总之,
- 可以使用
selectMethod=cursor
应用程序性能较低? -- 由于不同的原因,任何一种方法都会降低性能。经过一定的结果集大小,cursor
可能仍然更可取。请参阅下文了解何时使用其中一种或另一种 - 是
selectMethod=
JDBC 连接上的应用程序透明设置? -- 它是透明的,但如果内存使用量显着增长到足以占用其客户端系统(以及相应的服务器)或使客户端完全崩溃,它仍然可能会破坏他们的应用程序 - 更一般地说,什么时候应该使用
cursor
与direct
? ——我个人使用cursor
当处理可能很大或无限制的结果集时。然后,在给定足够大的批量大小的情况下,对往返开销进行摊销,并且我的客户端内存占用量是可预测的。我用direct
当我期望的结果集的大小低于我使用的任何批量大小时cursor
, ,或以某种方式绑定,或者当内存不是问题时。