首先發布的問題,我提前道歉,任何失誤。 該表包含分配給團隊的記錄,初始分配由另一個進程完成。通常情況下,我們必須重新分配代理商的記錄,並將其平均分配給團隊的其他成員。我們一個接一個地手工完成,這很麻煩。所以我想出了這個解決方案:SQL Server 2008是否有更高效的方式來執行此更新循環?
DECLARE @UpdtAgt TABLE (ID INT, Name varchar(25))
INSERT INTO @UpdtAgt
VALUES (1, 'Gandalf')
,(2,'Hank')
,(3,'Icarus')
CREATE TABLE #UpdtQry (TblID varchar(25))
INSERT INTO #UpdtQry
SELECT ShtID
FROM TestUpdate
DECLARE @RowID INT
DECLARE @AgtID INT
DECLARE @Agt varchar(25)
DECLARE @MaxID INT
SET @MaxID = (SELECT COUNT(*) FROM @UpdtAgt)
SET @AgtID = 1
--WHILE ((SELECT COUNT(*) FROM #UpdtQry) > 0)
WHILE EXISTS (SELECT TblID FROM #UpdtQry)
BEGIN
SET @RowID = (SELECT TOP 1 TblID FROM #UpdtQry)
SET @Agt = (SELECT Name FROM @UpdtAgt WHERE ID = @AgtID)
UPDATE TestUpdate
SET Assignment = @Agt
WHERE ShtID = @RowID
DELETE #UpdtQry WHERE TblID = @RowID
IF @AgtID < @MaxID
SET @AgtID = @AgtID + 1
ELSE
SET @AgtID = 1
END
DROP TABLE #UpdtQry
這實際上是我第一次嘗試這樣做的深入。 100行的更新大約需要30秒。 UPDATE表TestUpdate只有CLUSTERED索引。我怎樣才能讓這更高效?
編輯:我沒有在我的解釋中很好地定義@UpdtAgt和#UpdtQry表。 @UpdtAgt將持有正在重新分配記錄的代理,並且每次使用時都可能會更改。 #UpdtQry將有一個WHERE子句來定義哪些代理記錄將被重新分配,同樣,這將隨着每次使用而改變。我希望這能讓這個更清楚一點。再一次,道歉沒有得到正確的第一次。
編輯2:我評論了舊的WHILE子句並插入了HABO建議的子句。再次感謝HABO。
哪裏是'TestUpdate'表結構?看起來像一個'CTE'可以完成這項工作 – Sami
當檢查一行或多行的存在時,使用['EXISTS']會更高效(https://msdn.microsoft.com/zh-cn/library/ms188336 .aspx)而不是獲取確切的[COUNT](https://msdn.microsoft.com/en-us/library/ms175997.aspx),然後檢查它是否大於零。通常,不使用ORDER BY,使用'TOP'會被忽視。 – HABO
HOLY CRAP!那樣做了!在WHILE中使用EXISTS,而不是SELECT COUNT(*),從30秒到1秒以內。非常感謝你! – EFrost