【发布时间】:2020-05-15 23:44:15
【问题描述】:
我的存储过程中有游标。我已经更新到 while 循环以更快地执行。但是我的 while 循环需要很长时间。请帮我调试我的脚本。请找到我已删除光标并使用 while 循环更新的以下代码。我已经比较了相同的输出。但是与光标相比,这里需要很长时间。
DECLARE @orderArray INT
,@LeftTSMKEY NVARCHAR(250)
,@ListElid NVARCHAR(250)
,@ListType NVARCHAR(250)
,@ListType_Prev NVARCHAR(250)
,@inc INT
SET @ListType_Prev = ''
SET @inc = 0
DECLARE @cnt INT
DECLARE @t_cnt INT
DECLARE @Modules TABLE (
ID INT IDENTITY(1, 1)
,ListElid VARCHAR(4000)
,ListType VARCHAR(30)
,orderArray VARCHAR(4000)
,LeftTSMKEY VARCHAR(30)
)
INSERT INTO @Modules (
ListElid
,ListType
,orderArray
,LeftTSMKEY
)
SELECT ListElid
,ListType
,orderArray
,LeftTSMKEY
FROM QAT_ListElid
ORDER BY ListType
,orderArray
SET @cnt = 1
SELECT @t_cnt = count(*)
FROM @Modules
PRINT @t_cnt
PRINT 'loop started in ' + cast(getdate() AS NVARCHAR(30))
WHILE @cnt <= @t_cnt
BEGIN
SELECT @ListElid = ListElid
,@ListType = ListType
,@orderArray = orderArray
,@LeftTSMKEY = LeftTSMKEY
FROM @Modules
WHERE ID = @cnt
IF @ListType <> @ListType_Prev
BEGIN
SET @inc = 0
SET @ListType_Prev = @ListType
END
ELSE IF @ListType = @ListType_Prev
BEGIN
SET @inc = @inc + 1
END
IF @inc <> @orderArray
BEGIN
INSERT [QAT_ListElid2] (
[ListElid]
,[ListType]
,[orderArray]
,[LeftTSMKEY]
)
VALUES (
@ListElid
,@ListType
,@inc
,@LeftTSMKEY + CAST(@inc AS NVARCHAR(10)) + ']'
)
END
SET @cnt = @cnt + 1
END
【问题讨论】:
-
你为什么首先使用
CURSOR(WHILE),这将是我的问题。另外,whatCURSOR,你永远不会在上面声明一个。 -
我已移除光标并使用了 while 循环。还需要很长时间
-
“我已经删除了光标并使用了while循环” 那你为什么要问
CURSOR?不管怎样,是的,它会很慢。 SQL 不是一种编程语言,它是一种查询语言。您需要使用基于集合的解决方案。WHILE(或CURSOR)几乎总是意味着你设计错了。在 T-SQL 中使用这两种方法的原因非常很少,我可以自信地说 99.99%(或更多)的时间都错误地使用了 .您真正需要在这里告诉我们的是您的真正目标是什么,然后我们可以帮助您构建基于集合的解决方案。 -
只有在传统查询不起作用时才使用游标。游标总是存在性能问题。
-
@Larnu:谢谢你的信息。我需要优化我的脚本。请帮我解决这个问题。光标需要 2:00 小时才能运行我的 sp 。我想换。
标签: sql sql-server optimization while-loop cursor