Sql server 2012 SQL Server-While循环vs";本地静态只读转发;光标

Sql server 2012 SQL Server-While循环vs";本地静态只读转发;光标,sql-server-2012,cursor,Sql Server 2012,Cursor,我在我的应用程序中创建了许多游标,以便在每次游标单次运行时执行逐行操作。我只选择了500或1000条记录,以便游标可以在单次运行时尽快完成,换句话说,我为单次游标运行选择了有限数量的记录 为了更快地执行游标,并且不在服务器上加载,我使用了以下两种声明游标的方法 声明1: 声明DB\U CURSOR\U 01 CURSOR LOCAL STATIC READ\U ONLY FORWARD\U ONLY FOR 声明2: 声明DB\u游标\u 02游标快进 注意:我没有使用游标的默认声明,我使用其他

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

为了更快地执行游标,并且不在服务器上加载,我使用了以下两种声明游标的方法

声明1: 声明DB\U CURSOR\U 01 CURSOR LOCAL STATIC READ\U ONLY FORWARD\U ONLY FOR

声明2: 声明DB\u游标\u 02游标快进

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

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


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

SQL Server中的游标速度非常慢。在其他RDBMS上,例如Sybase,它们是正常的

以下是如何处理这些问题的实际方法:

根据我对老掉牙的代码进行“优化”的经验,游标的主要问题是当它们基于复杂查询时。所谓复杂查询,我指的是具有多个联接和/或复杂联接条件的查询。 游标所做的是,对于每个迭代,它都必须运行这个连接操作,这可能比循环体中的操作花费更多的时间

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

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

我见过一些特别“狡猾”的代码,其中:

  • 查询表以使用游标的一个获取变量作为筛选器返回单个值。-此表应
    连接到主游标查询。这样,此表将只查询一次,并将结果保存到临时表中
  • 查询表以根据某些条件返回一些数据,然后再次查询以根据相同条件返回更多数据(不同列)。-这两个选项应合并为一个选项,以便一次返回所有数据(所有列)
如果你有嵌套的游标(一个在另一个里面),它就是杀手级的。尝试删除嵌套

如果有许多地方有游标,请优先修复符合上述情况之一的游标

另一方面,当循环开启时,不会拯救您。您仍然需要使用临时表,并在临时表上有适当的索引。见:


上面的博客链接讨论了性能以及游标选项的建议。

使用临时表的while循环会是什么样子?您确定不能用单个更新(例如临时表上的更新)替换游标吗?我们曾经使用游标开发大型迁移,单个迁移需要数小时才能运行。然后我们意识到,用简单的更新来替换所有游标非常容易,这使得迁移速度比游标解决方案快得多。@IngoB在我的情况下,我不仅仅是在单个表上进行更新,在我的游标下,我正在做一些操作,比如进行一些计算,执行其他select语句,然后将数据插入其他表中。这只是一个例子,我可能有不同的游标,它们执行不同的操作。@IngoB这里你可以找到while循环和temp表的例子。好的,我明白了,但是我不能想象while循环快得多。我知道你说的“做很多操作”是什么意思,但是你真的试着去做基于集合的操作吗?我认为我们的案例无法想象它能起作用,但它确实起作用了,而且并不复杂。发布一个(简单的)示例,说明您认为无法将其转换为基于集合的操作。