【问题标题】:JDBC connection to very busy SQL 2000: selectMethod=cursor vs selectMethod=direct?与非常繁忙的 SQL 2000 的 JDBC 连接:selectMethod=cursor vs selectMethod=direct?
【发布时间】:2010-09-01 22:13:34
【问题描述】:

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

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

当 API 游标属性或 属性设置为任何其他 比他们的默认值,OLE DB SQL Server 和 SQL 的提供程序 服务器 ODBC 驱动程序使用 API 服务器 游标而不是默认结果 套。对 API 函数的每次调用 获取行生成一个 往返服务器以获取 API 服务器游标中的行。

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

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

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

所以,我的问题是:

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

还有cross-posted to SF

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

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

【问题讨论】:

  • IIRC,你是对的。不过,这看起来确实像一个 ServerFault 问题,也是一个 SO 问题。你也可以在sqlservercentral.com 上提问。
  • 我已经在 twitter 的 #sqlhelp 标签上提到了它。那里也没有咬人。我认为跨多个 SO 站点交叉发布问题被认为是不好的形式,对吧?
  • 我最好的猜测是他们应该尝试一下。也许他们有 UnitTests,他们可以使用更改的连接字符串(或一个小测试应用程序)对数据库触发。
  • 我不明白为什么会这样,而且 Q 一直被交叉发布——尤其是当它们从一个站点“审核”到另一个站点时,剩下 2 个副本。如果您在一个站点上获得了好的答案,请务必链接回另一个站点(以帮助未来的搜索者)。

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


【解决方案1】:

简单地说,

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

总之,

  • 使用selectMethod=cursor 会降低应用程序性能吗? -- 出于不同的原因,任何一种方法都会降低性能。超过一定的结果集大小,cursor 可能仍然更可取。请参阅下文了解何时使用其中一种
  • selectMethod= 是 JDBC 连接上的应用程序透明设置吗? -- 它是透明的,但如果内存使用量增长到足以占用他们的客户端系统(并且相应地,您的服务器)或完全崩溃客户端
  • 更一般地说,什么时候应该使用cursordirect——我个人在处理可能很大或无限的结果集时使用cursor。然后,给定足够大的批处理大小,来分摊往返开销,并且我的客户端内存占用是可预测的。当我期望的结果集的大小已知低于我使用cursor 使用的任何批量大小,或者以某种方式绑定,或者内存不是问题时,我使用direct

【讨论】:

  • 谢谢,vladr。听起来它的设置需要一些测试。我知道应用服务器很忙,所以当他们关闭它时,可能是内存问题导致了一些问题。
【解决方案2】:

使用selectMethod=cursor 会阻止SQL Server 使用Parallel Query Processing,这可能会对性能产生很大影响,例如:

  • 您有许多 CPU 内核(谁没有?)
  • 您已通过分区表优化了数据库
  • 您正在运行大量聚合查询(sum()count() 等)

最后,微软states如下:

(selectMethod=direct) 在应用程序处理所有行时提供最快的性能。

您绝对应该尝试看看设置 selectMethod=direct 是否对您有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-26
    • 2014-05-15
    • 2022-08-19
    • 2012-11-03
    • 1970-01-01
    • 1970-01-01
    • 2017-07-19
    • 1970-01-01
    相关资源
    最近更新 更多