(最先发布于 SO,但没有得到任何答案。交叉发布以覆盖更广泛的受众,因为它是跨学科的。)
在尝试帮助应用程序开发团队解决 SQL 2000 服务器上的一些性能问题的过程中,我运行了 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 服务器游标而不是默认结果集。每次调用提取行的 API 函数都会生成一次往返服务器的请求,以从 API 服务器游标中提取行。
更新:他们有多个 Java 应用程序使用指定的 JDBC 连接到 SQL 服务器selectMethod=cursor
(而不是selectMethod=direct
)。
从我的 DBA 角度来看,这很烦人(它会用无用的垃圾弄乱跟踪),并且很可能会导致许多额外的应用程序到 SQL 服务器往返,从而降低整体性能。
他们显然selectMethod=direct
以非常有限的方式进行了测试(仅更改了约 60 个应用程序中的一个)并且遇到了某种问题(我不知道其技术细节)。
所以,我的问题是:
selectMethod=cursor
vs对已经很繁忙的 SQL 2000 服务器的性能有何影响direct
?(我曾推测增加 SQL 和 APP 服务器之间的往返次数不会带来任何好处。我错了吗?)- 这是
selectMethod
一个应用程序透明的设置吗?如果我们更改它,这会破坏他们的应用程序吗? - 何时应使用
cursor
vsdirect
?是否有某些类型的应用会从其中一种方式中获益?
更新:找到了驱动程序参数的名称,这保证了对标题、正文和标签进行重大编辑。
更新:添加了悬赏。还为 SO 问题(更侧重于应用程序行为)添加了悬赏。谢谢!
答案1
简要地,
selectMethod=cursor
- 理论上需要更多服务器端资源比
selectMethod=direct
- 最多只能加载批量大小一次性将记录写入客户端内存,从而实现更可预测的客户端内存占用
- 理论上需要更多服务器端资源比
selectMethod=direct
- 理论上需要的服务器端资源比
selectMethod=cursor
- 会将整个结果集读入客户端内存(除非驱动程序本身支持异步结果集检索),然后客户端应用程序才能对其进行迭代;这可以通过两种方式降低性能:
- 如果客户端应用程序的编写方式使得在遍历结果集的一小部分后就停止处理(它
direct
已经支付了检索数据的成本,它基本上会丢弃这些数据;cursor
浪费最多批量大小- 1 行 - 提前终止条件可能应该在 SQL 中重新编码,例如SELECT TOP
或窗口函数) - 由于潜在的垃圾收集和/或与内存占用增加相关的内存不足问题,导致结果集较大时的性能降低
- 如果客户端应用程序的编写方式使得在遍历结果集的一小部分后就停止处理(它
- 理论上需要的服务器端资源比
总之,
- 能否使用
selectMethod=cursor
较低性能的应用程序?-- 出于不同的原因,这两种方法都会降低性能。超过一定结果集大小后,cursor
可能仍然是更好的选择。请参阅下文,了解何时使用其中一种 selectMethod=
JDBC 连接上是否存在应用程序透明的设置?——它是透明的,但如果内存使用量增长到足以占用他们的客户端系统(以及相应的服务器)或导致客户端完全崩溃,它仍然会破坏他们的应用程序- 更一般地说,什么时候应该使用
cursor
vsdirect
?-- 我个人cursor
在处理可能很大或无限制的结果集时使用。如果批处理大小足够大,往返开销就会摊销,并且我的客户端内存占用是可预测的。direct
当我预期的结果集大小小于我使用的批处理大小cursor
或以某种方式受限时,或者当内存不是问题时,我会使用它。
干杯,V。