有人可以解释一下使用RowCounter的While循环是否比在SQL服务器中使用ROW_NUMBER更快或更慢?
或者没有区别?
现有的存储过程太复杂了,无法将其全部放在View中并且速度非常慢..这是While循环,但是如何在Sql Server 2008 R2中使用ROW_NUMBER来完成,并且会有任何性能优势?
DECLARE @StopRow AS INT
SELECT @StopRow = MAX(RowID)
FROM #Temp1
DECLARE @RowCounter AS INT
SET @RowCounter = 1
DECLARE @colID INT
WHILE (@RowCounter <= @StopRow)
BEGIN
SELECT @colID = colID
FROM #Temp1
WHERE colRowID = @RowCounter
IF (
EXISTS (
SELECT ParentColID
FROM ParentTable a WITH (NOLOCK)
JOIN MoreTableData b WITH (NOLOCK) ON a.priID = b.priID
AND colID = @colID
WHERE anotherID NOT IN (
SELECT anotherID
FROM @anotherTempTable
)
)
)
UPDATE #Temp1
SET aFlag = 0
WHERE colRowID = @RowCounter
SET @RowCounter = @RowCounter + 1
END
现在发现这个StackOverflow,我理解基于SET(UPDATE)的verbage .. How to convert a loop in SQL to Set-based logic
答案 0 :(得分:2)
为什么你需要任何循环?可以在一个UPDATE
吗?
UPDATE T
SET aFlag = 0
FROM #Temp1 AS T
WHERE EXISTS (
SELECT ParentColID
FROM ParentTable a WITH (NOLOCK)
JOIN MoreTableData b WITH (NOLOCK)
ON a.priID = b.priID
AND a.colID = t.colID
WHERE anotherID NOT IN (
SELECT anotherID
FROM @anotherTempTable
)
)
未经测试。
答案 1 :(得分:1)
通常,基于集合的解决方案比基于游标的解决方案提供更好的性能。
如果考虑性能,我会尝试使用基于集合的解决方案重写我的解决方案:
UPDATE t1
SET aFlag = 0
FROM #Temp1 t1
WHERE colRowID BETWEEN 1 AND (SELECT MAX(RowID) FROM #Temp1)
AND EXISTS
(
SELECT ParentColID
FROM ParentTable a
JOIN MoreTableData b ON a.priID = b.priID
AND colID = t1.colID
WHERE anotherID NOT IN
(
SELECT anotherID
FROM @anotherTempTable
)
)
然后,在开发/服务器服务器上,我将使用SQL跟踪/扩展事件会话来跟踪以下主要KPI:持续时间,CPU,[逻辑]读取,我将比较这两个解决方案(基于光标与基于集合)
注意#1:(SELECT MAX(RowID) FROM #Temp1)
子查询应该只进行一次评估,因为它不是相关的子查询。
注意#2:尝试用NOT EXISTS替换NOT IN。 Reason