SQL ServeR语言 while 循环与"LOCAL STATIC READ_ONLY FORWARD_ONLY"游标



我在应用程序中创建了许多游标,以便在每次游标单次运行中逐行执行操作,我只选择了 500 或 1000 条记录,以便游标可以在单次运行中像 postilion 一样快地完成,换句话说,我为单游标运行选择了有限数量的记录。

为了更快地执行游标并且不给服务器带来负载,我使用了以下两种声明游标的方法。

声明1:声明DB_CURSOR_01游标本地静态

READ_ONLY FORWARD_ONLY 声明2:声明DB_CURSOR_02 游标FAST_FORWARD

注意:我没有使用光标的默认声明,我正在使用其他类型的光标来使其工作得更快,据我所知,上面提到的声明 1 比声明 2 更快,如果我错了,请纠正我。

问:另一种逐行操作的方式是通过"while循环使用临时表"。所以现在我的问题是,如果我使用临时表将所有光标转换为 while 循环,它是否有助于提高服务器性能?

实际上,我们的 DBA 指出,由于游标,服务器性能正在受到影响,如果我付出那么多努力将所有这些游标转换为 while 循环,它会给我带来性能优势吗? 或者我在上面提到的声明 1 中声明游标的方式将与 while 循环具有相同的性能?

SQL Server 中的游标非常慢。在其他RDBMSes.e.gSybase上,它们是可以的。

以下是如何处理它们的实用方法:

根据我"优化"旧狡猾代码的经验,游标的主要问题是当它们基于复杂的查询时。复杂查询是指具有多个连接和/或复杂连接条件的查询。 游标的作用是,对于每次迭代,它都必须运行此联接操作,这可能比循环主体内的操作花费更多时间。

在这种情况下,将单个选择运行到临时表中,然后在游标中使用临时表会更有效,另一种方法是使用STATICINSENSITIVE关键字 (MSDN(。要考虑的一个重要方面是并发性;通过将主游标查询的结果保存到临时表中,可以防止对基础表的更改对游标可见。

要考虑的第二个方面是游标内的选择查询。这一点很重要,因为每个查询都是针对每个游标迭代运行的,因此对消耗大量资源的大型表进行选择。

我看过一些特别"狡猾"的代码,其中:

  • 查询表以使用游标的提取变量之一作为过滤器返回单个值。 - 此表应JOIN到主游标查询。这样,此表将仅查询一次,并将结果保存到临时表中。
  • 查询
  • 表以根据某些条件返回一些数据,然后再次查询以基于相同条件返回更多数据(不同的列(。 - 这两个选择应合并为一个,以便可以一次返回所有数据(所有列(。

如果您有嵌套游标(一个在另一个内部(,则它是杀手级的。尝试删除嵌套。

如果您有很多带有光标的地方,请优先修复与上述情况之一匹配的地方。

附言虽然循环是自己的不会拯救你。您仍然需要使用临时表并在临时表上具有适当的索引。请参阅: https://dba.stackexchange.com/questions/84365/why-choose-a-top-query-and-temporary-table-instead-of-a-cursor-for-a-loop

上面链接到 Aaron Bertrand 博客,该博客讨论了性能以及光标选项的建议。

相关内容

最新更新