JDBC 连接到非常繁忙的 SQL 2000 : selectMethod=cursor vs selectMethod=direct?

标签 jdbc sql-server-2000 database-cursor selectmethod

在尝试帮助一个应用程序开发团队解决 SQL 2000 服务器上的性能问题(来自不同应用程序服务器上的一堆 Java 应用程序)的过程中,我运行了 SQL 跟踪并发现对数据库的所有调用都充满了 API服务器游标语句(sp_cursorprepexec、sp_cursorfetch、sp_cursorclose)。

看起来他们正在指定一些强制使用服务器端游标的连接字符串属性,一次只检索 128 行数据:(来自 http://msdn.microsoft.com/en-us/library/Aa172588 )

When the API cursor attributes or properties are set to anything other than their defaults, the OLE DB provider for SQL Server and the SQL Server ODBC driver use API server cursors instead of default result sets. Each call to an API function that fetches rows generates a roundtrip to the server to fetch the rows from the API server cursor.



更新 : 有问题的连接字符串是一个 JDBC 连接字符串参数,selectMethod=cursor (启用我们上面讨论的服务器端游标)与替代 selectMethod=direct .他们一直在使用selectMethod=cursor作为所有应用程序的标准连接字符串。

从我的 DBA 的角度来看,这很烦人(它用无用的垃圾使跟踪变得困惑),并且(我推测)会导致许多额外的应用程序到 SQL 服务器往返,从而降低整体性能。

他们显然确实测试了更改(只是大约 60 个不同的应用程序连接之一)到 selectMethod=direct但遇到了一些问题(我没有详细信息),并且担心应用程序崩溃。

所以,我的问题是:
  • 可以使用selectMethod=cursor较低的应用程序性能,正如我试图争论的那样? (通过增加 SQL 服务器上已经有非常高的查询/秒所需的往返次数)
  • selectMethod= JDBC 连接上的应用程序透明设置?如果我们改变它,这会破坏他们的应用程序吗?
  • 更一般地说,什么时候应该使用 cursor对比 direct ?

  • 还有cross-posted to SF .

    编辑 :收到了需要对标题、问题和标签进行重大编辑的实际技术细节。

    编辑 : 增加赏金。还为 SF 问题添加了赏金(此问题侧重于应用程序行为,SF 问题侧重于 SQL 性能。)谢谢!

    最佳答案

    简要地,

  • selectMethod=cursor
  • 理论上需要more server-side resourcesselectMethod=direct
  • 一次最多只能将批量大小的记录加载到客户端内存中,从而导致更可预测的客户端内存占用
  • selectMethod=direct
  • 理论上比 selectMethod=cursor 需要更少的服务器端资源
  • 将整个结果集读入客户端内存(除非驱动程序本身支持异步结果集检索),然后客户端应用程序才能对其进行迭代;这个可以通过两种方式降低性能 :
  • 如果客户端应用程序的编写方式是在仅遍历一小部分结果集后停止处理,则会降低大型结果集的性能(使用 direct 它已经支付了检索数据的成本,它将基本上丢弃;使用cursor 浪费被限制在最多批量大小 - 1 行 - 提前终止条件可能应该在 SQL 中重新编码,例如作为 SELECT TOP 或窗口函数)
  • 由于潜在的垃圾收集和/或与内存占用增加相关的内存不足问题导致大型结果集的性能下降

  • 总之,
  • 可以使用selectMethod=cursor应用程序性能降低? -- 出于不同的原因,任何一种方法都会降低性能。超过一定的结果集大小,cursor可能仍然是可取的。请参阅下文了解何时使用其中一个或另一个
  • selectMethod= JDBC 连接上的应用程序透明设置? -- 它是透明的,但如果内存使用量增长到足以占用他们的客户端系统(以及相应地,你的服务器)或使客户端完全崩溃,它仍然会破坏他们的应用程序
  • 更一般地说,什么时候应该使用 cursor对比 direct ? -- 我个人使用cursor在处理可能很大或无界的结果集时。然后,给定足够大的批处理大小,来分摊往返开销,并且我的客户端内存占用是可预测的。我用 direct当已知我期望的结果集的大小低于我在 cursor 中使用的任何批量大小时,或以某种方式绑定(bind),或者当内存不是问题时。
  • 关于JDBC 连接到非常繁忙的 SQL 2000 : selectMethod=cursor vs selectMethod=direct?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3622500/

    相关文章:

    postgresql - 在字符串中实现每个查询的结果

    java - 应用程序未在 64 位计算机上运行

    sql - 重置或更新数据库表中的行位置整数

    python - 错误 : Cursor' object has no attribute '_last_executed

    python - 如何使用 Python 获取游标对象的值

    oracle - 如何在JRuby Gradle项目中避免 “cannot load Java class oracle.jdbc.OracleDriver”?

    sql-server - 将 SQL Server 2000 安全地暴露在 Internet 上

    sql - 在 SQL Server 中使用 DATEPART 时出现错误的周数

    java - 特定查询直接运行良好,或者对其进行任何更改但在当前状态下运行时间更长

    mysql - 传递 jdbc 数据源与传递 Connection 对象 - 从 servlet 到 java 类