【发布时间】:2011-10-16 04:34:54
【问题描述】:
我最近有关于在 TSQL 中使用游标的争论......
首先,我不是辩论中的啦啦队长。但是每次有人说 cursor 时,总会有一些傻瓜(或 50 个)用强制性的'光标是邪恶的'口头禅猛扑过去。我知道 SQL-Server 针对基于集合的操作进行了优化,也许游标确实是邪恶的化身,但如果我想在这背后加上一些客观的想法......
这就是我的想法:
-
游标和集合操作之间的唯一区别是性能之一吗?
编辑:有一个很好的例子,它不仅仅是性能问题 - 例如为一个 id 列表反复运行单个批处理,或者执行逐行存储在表字段中的实际 SQL 文本。
-
跟进:游标总是表现更差吗?
- 编辑:@Martin 展示了一个很好的案例,即 Cursors 相当显着地胜过基于集合的操作。我怀疑这不会是你经常太做的事情(在你求助于某种 OLAP / 数据仓库类型的解决方案之前),但尽管如此,这似乎是一个案例没有光标你真的活不下去。
- reference to TPC benchmarks 建议光标可能比人们普遍认为的更具竞争力。
- reference to memory-usage optimizations 用于游标自 Sql-Server 2005 起
-
你能想到游标比基于集合的操作更适合解决的问题吗?
-
编辑:基于集合的操作实际上不能
Execute存储过程等(参见上面第 1 项的编辑)。 - 编辑:在聚合大型数据集时,基于集合的操作比逐行操作要慢得多。
-
编辑:基于集合的操作实际上不能
- Article from MSDN 解释他们的观点 最常见的问题,人们求助于游标(和一些 解释更有效的基于集合的技术。)
- 微软在2008 Transact SQL Reference on MSDN 中(含糊地)说:“......有时最好一次处理一行结果”,但没有给出任何关于他们所指案例的示例到。
大多数情况下,如果/当我对各种应用程序进行任何重大升级时,我会在我的旧代码中将游标转换为基于集合的操作,只要能从中获得一些东西。 (我在很多时候倾向于懒惰而不是纯粹——也就是说,如果它没有坏,就不要修理它。)
【问题讨论】:
-
"如果没有损坏,请不要修复它。" - 我认为您的目标是“如果它没有坏,就不要修复它”:-)
-
@Damien -- 好吧,我已经把它弄坏了。 :-)
-
到目前为止,我有 4 个非常有见地的答案,考虑到它们都是有效的,我只想将得票最多的一个标记为答案。我在我最初的问题中总结了答案,我希望人们在看到一些被遗漏的东西时仍然会为此做出贡献。例如——我仍然想测试的一件事是在一个字段中聚合字符串(即创建一个分隔列表),以及游标在大型数据集上是否优于基于集合的解决方案,例如链接中的合并解决方案上面的问题 3(文章来自 MSDN)。无论如何,谢谢。
标签: tsql stored-procedures database-cursor set-based