MS SQL服务器 - 如果是一个CURSOR好?(MS SQL Server - When is

2019-07-19 16:59发布

当我写存储过程等很多时候,我使用光标在第一,后来找到我的一些程序性能问题。

我读的每一件事说游标是可怕的,造成不必要的锁定等,性能测试证明是相同的。

我的问题是,当你用光标在什么场合都是他们有用的还是不错的?

如果没有使用,他们为什么会做出这样的坏控制结构/ SQL类型?

Answer 1:

通常情况下,他们要避免,但特点是有原因的,有次去使用它们。 我说不需要我见过的游标的90%以上。 如果您使用的是他们的CRUD操作,这几乎总是可以在基于集合的方式重做。 我经常看到人们用游标,因为他们不知道如何使用连接在更新或删除,或者他们可以插入使用select statment而不是值条款。 另一种不必要的使用,当人们认为他们需要他们,实际上可以很容易地用一个case语句来处理稍微复杂的处理。

游标有时计算像总运行速度更快。

光标也很方便了,它被设置在同一时间只能处理一个输入值的存储过程的多次执行。 我不使用这个功能来运行用户存储特效(除非我知道我会打的非常小的数据集),但需要运行对多表系统的特效时,它是数据库管理员非常方便。

如果要创建在SQL邮件(不这样做的最好的地方,但在某些系统中这也正是他们这样做)和不希望的电子邮件的整个观众看到其他人在名单上,你要个性化的每个有关收件人信息的电子邮件,游标是要走的路。

光标或循环也可以用来处理记录批次如果整个基于集合的插入/更新/删除将花费太长时间,并锁定了表。 这是一种光标和基于集合的解决方案之间的混合,并往往是在生产系统的巨大变化最好的之一。



Answer 2:

我问在SQL Server团队一次一个人,如果你可以添加一个功能,它将使产品更好地为大家会是什么感觉?

他的反应是“添加? 呵呵,我会采取一个客场。 如果你摆脱光标你强迫程序员在世界各地开始在一套基于这样思考的事情,这将是最大的世界范围内增加DB的性能你永远不会看到。”

就我而言不过我倾向于看到一个模式,似乎有很多谁使用游标,因为他们需要能够在同一时间做一次手术一个元素,怀念过去的时尚WHILE循环概念的程序编码器。 相同的基本理念没有光标的开销。 还没靠近快速/有效的东西SET为基础,但90%的时候有人声称当时“我不能做这一套基础的,我必须使用游标”我可以让他们使用while循环做到这一点。



Answer 3:

这里有一个相当自以为是的家伙的文章,谁给不使用游标和一些答案至于他们是如何来到一个道理: 必须有15种方法失去你的光标 。



Answer 4:

该MCTS准备手册SQL Server 2008的,我是学建议使用外部CLR代码任何地方,光标会在T-SQL是必需的,尤其是现在,SQL Server 2008支持的自定义聚合函数。

5年前,我与他们合作进行广泛的报表功能,但我不认为我能想出一个很好的使用情况他们现在。 CLR聚集和功能,同样执行到内置的聚合函数。



Answer 5:

只有我会用他们的时间是在无论是被光标内部完成绝对有一次做一个项目,在那里无论是被光标内部完成需要很长时间光标的开销淡入渺小。

例如:数据库备份,完整性检查,索引重建。 总之,管理任务。



Answer 6:

妈呀,我怎么忘了分组依据? 我把基于游标查询你看到下面,并与之后的一个替代它。 现在,我得到一个结果集所以与在PHP中使用sqlsrv_next_result()没有问题。

DECLARE @thisday datetime;

DECLARE daycursor CURSOR FOR
SELECT DISTINCT DATEADD(day, 0, DATEDIFF(day, 0, TimeCollected)) as thisday
FROM computerusedata

OPEN daycursor;
FETCH NEXT FROM daycursor
INTO @thisday;
WHILE @@FETCH_STATUS = 0
    BEGIN
    select distinct left(ComputerName,5) as CompGroup,DATEADD(day, 0, DATEDIFF(day, 0, TimeCollected)) as day
    FROM computerusedata
    where DATEADD(day, 0, DATEDIFF(day, 0, TimeCollected)) = @thisday
    order by CompGroup;
    FETCH NEXT FROM daycursor;
    END;
CLOSE daycursor;
DEALLOCATE daycursor;";


select DATEADD(day, 0, DATEDIFF(day, 0, TimeCollected)) as day,left(ComputerName,5) as CompGroup
from ComputerUseData
group by DATEADD(day, 0, DATEDIFF(day, 0, TimeCollected)),left(ComputerName,5)
order by day,CompGroup


Answer 7:

我通常不使用游标,但是当我这样做,它必须是我在本地运行一个“一次性”查询或日常工作。 您不希望生产代码中调用,将响应Web请求频繁调用像游标来避免。



Answer 8:

1时),你需要做的事情,你不能用一组配合操作;或者2)它没有任何意义通过使从应用层反复调用做同样的工作光标是有用的。 或者有时候你有必须保留在数据库层上的过程中,你根本无法突破回给应用层中游遍历一些结果集。

一个建议我会做,虽然,是人们使用游标变量,而不是普通游标,因为你避免周围正常光标光标分配/释放的问题。 与正常的光标,如果不取消分配他们,他们坚持,它可以是内存泄漏的来源。 不那么与基于可变游标(即DECLARE @cursor CURSOR)。

底线是,避免他们,如果你可能可以,如果你做不到,最低限度,并明智地使用它们。



Answer 9:

您可以使用光标单独重建或重新组织表的索引
除非有正在运行的一种方式ALTER INDEX ...作为基于集合的操作。



文章来源: MS SQL Server - When is a CURSOR good?