【发布时间】:2009-04-29 14:16:01
【问题描述】:
我必须计算一个涉及多个表中数据的值。我想知道与将数据读入数据集(使用简单的选择存储过程)然后循环遍历记录相比,使用带有游标的存储过程是否会提供性能优势?数据集不大,由6个表组成,每个表大约有10条记录,主要是GUID、几个nvarchar(100)字段、一个float列和一个nvarchar(max)。
【问题讨论】:
我必须计算一个涉及多个表中数据的值。我想知道与将数据读入数据集(使用简单的选择存储过程)然后循环遍历记录相比,使用带有游标的存储过程是否会提供性能优势?数据集不大,由6个表组成,每个表大约有10条记录,主要是GUID、几个nvarchar(100)字段、一个float列和一个nvarchar(max)。
【问题讨论】:
这可能取决于您可能要检索的数据集(集合越大,在 SQL Server 内部执行而不是传递它可能越合乎逻辑),但我倾向于认为,如果您正在寻找执行计算,在您的代码中进行,远离您的存储过程。如果您需要使用游标将数据拉到一起,就这样吧,但我认为应该避免使用它们来进行计算和其他非检索功能。
编辑:这个Answer 对另一个相关问题将给出游标与循环的一些优点和缺点。这个答案似乎与我之前关于缩放的断言(见上文)相冲突。似乎表明你得到的越大,你可能越想把它移到你的代码而不是存储过程中。
【讨论】:
光标的替代品
declare @table table (Fields int)
declare @count int
declare @i
insert inot @table (Fields)
select Fields
from Table
select @count = count(*) from @table
while (@i<=@count)
begin
--whatever you need to do
set @i = @i + 1
end
【讨论】:
游标应该更快,但如果你有很多用户运行它,它会消耗你的服务器资源。请记住,在 .Net 而非 SQL 中编写循环时,您拥有更强大的编码语言。
很少有不能使用基于标准集的 SQL 替换游标的情况。如果您在服务器上执行此操作,则可以使用基于集合的操作。关于你在做什么的更多细节?
如果您决定使用游标,请记住 FAST_FORWARD 只读游标将为您提供最佳性能,并确保您使用 deallocate 语句来释放它。光标提示见here
【讨论】:
游标应该更快(除非您在 SQL 而不是在 ADO.NET 中做一些奇怪的事情)。
也就是说,我经常发现只需做一些跑腿就可以消除光标。需要办理什么手续?
干杯,
埃里克
【讨论】: