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


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

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

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

UPDATE:有争议的连接字符串是JDBC连接字符串参数, selectMethod=cursor (这使得我们上面讨论过的服务器端游标)与替代方案相比 selectMethod=direct。他们一直在使用 selectMethod=cursor 作为所有应用程序的标准连接字符串。

从我的DBA角度来看,这只是令人讨厌(它使用无用的垃圾混乱了跟踪),并且(我推测)导致许多额外的app-to-SQL服务器往返,降低了整体性能。

他们显然测试了改变(只有60个不同的应用程序连接中的一个) selectMethod=direct 但经历了一些问题(我没有详细说明),并担心应用程序中断。

所以,我的问题是:

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

交叉发布到SF

编辑:收到实际的技术细节,保证对标题,问题和标签进行重大编辑。

编辑:添加了赏金。还为SF问题添加了赏金(这个问题主要关注应用程序行为,SF问题主要集中在SQL性能上。)谢谢!!


3535
2017-09-01 22:13


起源

IIRC,你是对的。尽管如此,这似乎与ServerFault问题一样多。你可能很聪明地问 sqlservercentral.com 太。 - Brock Adams
我在twitter上的#sqlhelp标签上提到过它。也没有叮咬。我认为在多个SO网站上交叉发布问题被认为是不好的形式,对吧? - BradC
我最好的猜测是他们应该尝试一下。也许他们有UnitTests,他们可以使用更改的连接字符串(或一个小测试应用程序)对数据库进行触发。 - Bobby
我不明白为什么会这样,并且Q会一直被交叉发布 - 特别是当他们从一个网站“审核”到另一个网站时,仍然有2个副本。如果您在一个站点上获得了良好的答案,请确保链接回另一个站点(以帮助未来的搜索者)。 - Brock Adams


答案:


简单地说,

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

综上所述,

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

11
2017-09-14 04:08



谢谢,vladr。听起来像是一个需要进行一些测试的设置。我知道应用程序服务器非常繁忙,所以也许这是一个内存问题,当他们关闭它时会导致一些问题。 - BradC


运用 selectMethod=cursor 阻止SQL Server使用 并行查询处理,这可能会产生很大的性能影响,例如:

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

最后,微软 状态 下列:

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

你一定要试着看看设置selectMethod = direct是否会对你产生影响。


0
2017-07-31 16:19