尝试永远不要循环,处理数据集.
您可以一次插入,更新,删除多行.这里是多行的示例插入:
INSERT INTO YourTable
(col1, col2, col3, col4)
SELECT
cola, colb+Colz, colc, @X
FROM ....
LEFT OUTER JOIN ...
WHERE...
Run Code Online (Sandbox Code Playgroud)
在查看循环时,请查看其内部的操作.如果只是插入/删除/更新,请重写以使用单个命令.如果有IF,请查看这些是否可以是插入/删除/更新的CASE语句或WHERE条件.如果是这样,请删除循环并使用set命令.
我已经采用循环并用基于集合的命令替换它们,并将执行时间从几分钟缩短到几秒钟.我已经采用了许多嵌套循环和过程调用的程序并保留了循环(不可能只使用插入/删除/更新),但是我删除了光标,并且看到了更少的锁定/阻塞和大量的性能提升.这里有两个比光标循环好的循环方法......
如果你必须循环,在一个集合上做这样的事情:
--this looks up each row for every iteration
DECLARE @msg VARCHAR(250)
DECLARE @hostname sysname
--first select of currsor free loop
SELECT @hostname= min(RTRIM(hostname))
FROM master.dbo.sysprocesses (NOLOCK)
WHERE hostname <> ''
WHILE @hostname is not null
BEGIN
set @msg='exec master.dbo.xp_cmdshell "net send '
+ RTRIM(@hostname) + ' '
+ 'testing "'
print @msg
--EXEC (@msg)
--next select of cursor free loop
SELECT @hostname= min(RTRIM(hostname))
FROM master.dbo.sysprocesses (NOLOCK)
WHERE hostname <> ''
and hostname > @hostname
END
Run Code Online (Sandbox Code Playgroud)
如果你有一套合理的项目(不是100,000)来循环,你可以这样做:
--this will capture each Key to loop over
DECLARE @msg VARCHAR(250)
DECLARE @From int
DECLARE @To int
CREATE TABLE #Rows
(
RowID int not null primary key identity(1,1)
,hostname varchar(100)
)
INSERT INTO #Rows
SELECT DISTINCT hostname
FROM master.dbo.sysprocesses (NOLOCK)
WHERE hostname <> ''
SELECT @From=0,@To=@@ROWCOUNT
WHILE @From<@To
BEGIN
SET @From=@From+1
SELECT @msg='exec master.dbo.xp_cmdshell "net send '
+ RTRIM(hostname) + ' '
+ 'testing "'
FROM #Rows WHERE RowID=@From
print @msg
--EXEC (@msg)
END
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
27996 次 |
| 最近记录: |