我先走了。

我100%属于设定操作阵营。但是,当整个所需的输入域上的设定逻辑导致一个很大的检索,以至于查询大大减慢,爬行或基本上花费无限的时间时会发生什么?

在这种情况下,我将使用一个很小的游标(或 while 循环)来处理可能最多的几十行(而不是我的目标数百万行)。因此,我仍在(分区子)集中工作,但我的检索运行得更快。

当然,更快的解决方案是从外部并行调用分区输入域,但这会引入与外部系统的交互,并且当可以通过串行循环实现“足够好的”速度时,可能不值得它(特别是在开发过程中)。

有帮助吗?

解决方案

当然,有很多地方游标可能比基于集合的操作更好。

一种情况是,如果您正在更新表中的大量数据(例如,SQL代理作业以按计划预先计算数据),那么您可以使用游标在多个小集合而不是一个大集合中执行此操作减少并发锁定的数量,从而减少与其他访问数据的进程发生锁争用和/或死锁的可能性。

另一种情况是,如果您想使用 sp_getapplock 存储过程获取应用程序级锁定,这在您希望确保多次检索由多个进程轮询的行时非常有用(< a href =“http://gregbeech.com/blogs/tech/archive/2008/06/11/retrieving-a-row-exactly-once-with-multiple-polling-processes-in-sql-server.aspx” rel =“nofollow noreferrer”>这里的例子)。

总的来说,我同意最好在可能的情况下开始使用基于集合的操作,并且只有在出于功能或性能原因需要时才转移到游标(有证据支持后者)。

其他提示

我有很多情况需要读取配置表中的行并生成和执行代码,或者在许多元编程方案中。

还有一些情况下,游标只是表现优异,因为优化器不够智能。在这些情况下,要么你的头脑中有元信息,而这些元信息根本没有通过表中的索引或统计信息显示给优化器,或者代码非常复杂,以至于连接(通常是重新连接)只是简单不能以基于游标的方式可视化它们的方式进行优化。在SQL Server 2005中,我认为CTE往往会使代码看起来更简单,但是优化器是否也认为它们更简单很难知道 - 它归结为将执行计划与您认为可以完成的方式进行比较最有效率和打电话。

一般规则 - 除非必要,否则不要使用游标。但是在必要的时候,不要给自己带来困难。

有很多不同的 光标行为.

  • 静态 vs 按键设置 vs 动态
  • 滚动、仅前进、快进
  • 是否不敏感
  • 乐观或只读或否
  • 本地与全球(至少这很容易)

你应该 从不使用光标 除非你可以 解释所有这些选项 以及哪些是 默认开启.

所以,我从来不这样做。

相反,当我想要在 T-SQL 中循环某些内容时......我将其加载到变量表中,这类似于 LOCAL STATIC SCROLL 游标...除了它可以被索引和连接(编辑:以及阻止使用并行性的缺点)。

偶尔你会得到一个需要游标的操作,但在T-SQL中它很少见。 Identity(int)列或序列在集合操作中以方式排序。计算可能在某些点发生变化的聚合(例如从地面累积声明到极限或超出点)本质上是程序性的,因此它们是光标的候选者。

其他候选者本质上是程序性的,例如循环配置表以及生成和执行一系列查询。

除了 David B 所说的话,我也更喜欢循环/表格方法。

除此之外,游标和循环/表方法的一个用例涉及极大的更新。假设你必须更新10亿行。在许多情况下,这可能不需要是交易性的。例如,它可能是一个数据仓库聚合,如果事情向南,您可以从源文件重建。

在这种情况下,最好以“块”进行更新,一次可能有100万或1000万行。这有助于将资源使用量降至最低,并允许在更新数十亿行时最大程度地同时使用计算机。循环/分块方法在这里可能是最好的。对不太好的硬件进行十亿行更新往往会导致问题。

在纯SQL环境中,我宁愿按照你的建议避开游标。但是一旦你跨越到过程语言(如PL / SQL),就会有很多用途。例如,如果您想要检索某些行并希望“执行”操作比用它们更新它更复杂的东西。

当您想要使用不同的输入值多次运行系统proc时,游标也很方便。我无意尝试将系统转换重写为基于集合,因此我将使用游标。此外,您通常会经历数量非常有限的物体。对于一次只插入一条记录的现有proc,你可以做同样的事情,但是从性能视图来看,如果要运行很多记录,这通常是一件坏事。那些我将重写为基于集合。

其他人讨论的运行总计可能会更快。

如果您是从数据库发送电子邮件(不是最好的想法,但有时它是您坚持使用的),那么光标可以确保当您发送相同的电子邮件时,客户a看不到客户b的电子邮件地址。

必须使用游标通常表明您正在数据库中执行应用程序中应该执行的操作。正如其他人所说,当存储过程计算运行总计时,或者当您生成代码和/或元编程时,通常需要使用游标。

但是你为什么要首先在存储过程中做这种工作?这真的是数据库服务器的最佳用途吗? T-SQL真的是生成代码时使用的正确语言吗?

当然,有时答案是“是的”,或者,更可能的是,“不,但这种方式更简单。”在我看来,保持简单,胜过一周中任何一天的过早优化。所以我使用游标。但是,当我认为我需要使用光标时,宇宙问我一个问题,我应该得到一个很好的答案。

如果某个表因某种原因未被索引,则游标将比其他迭代表的方法更快。我在中找到了这些信息。这篇关于去年SQL Server游标的博客

虽然作者赞成“仅作为最后手段使用”。方法(就像这里的每个人一样),她确实找到了一个或两个游标执行的案例以及其他可用的替代方案(包括Robert Rossney指出的运行总计)。在她提出的其他有趣观点中,她指出游标在存储过程中的运行效率高于临时查询。作者也非常出色地指出了我们所有与游标相关的性能问题何时开始出现。

博客文章包含实际代码,因此读者可以自己尝试查询并查看结果。

在计算游标总数和类似内容时,游标优于集合的一个操作就是。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top