Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 从循环更新(表锁定问题和CLR内存问题)_Sql_Sql Server_Sql Server 2012_Spatial - Fatal编程技术网

Sql 从循环更新(表锁定问题和CLR内存问题)

Sql 从循环更新(表锁定问题和CLR内存问题),sql,sql-server,sql-server-2012,spatial,Sql,Sql Server,Sql Server 2012,Spatial,我有一张有地理栏的桌子。我想根据查询结果更新行子集(~1000)的此值 我创建了一个视图,该视图将返回我想要的地理列+表中要更新的行的id 如果我运行查询 UPDATE A SET A.GeogCol = B.GeogCol FROM TableToUpdate A INNER JOIN UpdatedFrom_View B ON A.ID = B.ID 我将收到系统内存不足错误。发生这种情况的原因是它是32位sql server,VAS保留空间不足,因为我调用CLR函数来创建地理列。我不是服

我有一张有地理栏的桌子。我想根据查询结果更新行子集(~1000)的此值

我创建了一个视图,该视图将返回我想要的地理列+表中要更新的行的id

如果我运行查询

UPDATE A
SET A.GeogCol = B.GeogCol
FROM TableToUpdate A
INNER JOIN UpdatedFrom_View B
ON A.ID = B.ID
我将收到系统内存不足错误。发生这种情况的原因是它是32位sql server,VAS保留空间不足,因为我调用CLR函数来创建地理列。我不是服务器管理员,因此无法临时为VAS预订分配更多空间

如果我将其减少到
,其中A.ID介于0和100之间,并尝试手动执行此操作,则有时仍会出现此问题。我发现了一些麻烦的行(比平常更大的地理对象),如果我说WHERE
a.ID=@ID
,我可以更新这些行

我当时的想法是基于循环进行更新

DECLARE @ID INT
DECLARE @g GEOGRAPHY

DECLARE IDCursor CURSOR FOR SELECT ID FROM TableToUpdate
OPEN IDCursor

FETCH NEXT FROM IDCursor INTO @ID

WHILE @@FETCH_STATUS = 0
BEGIN
  SET @g = (SELECT GeogCol FROM UpdatedFrom_View WHERE ID = @ID)
  UPDATE TableToUpdate SET GeogCol = @g WHERE ID = @ID
  FETCH NEXT FROM IDCursor INTO @ID
END
CLOSE IDCursor
DEALLOCATE IDCursor
然而,这似乎与表锁定有关(我认为)。它现在已经运行了不到2天,更新了不到150条记录

作为参考,手动完成时,
更新表更新集GeogCol=@g其中ID=@ID
所需时间不到10秒

有更好的方法吗

--编辑

所以我决定测试一下

我写了这个查询,大约需要1秒的时间

UPDATE A
SET A.GeogCol = B.GeogCol
FROM TableToUpdate A
INNER JOIN UpdatedFrom_View B
ON  A.ID = B.ID
WHERE A.ID BETWEEN 1 AND 1
然后,我编写了一个存储过程,它执行完全相同的操作

CREATE PROCEDURE TestUpdate @IDLow INT, @IDHigh INT
AS
BEGIN
  UPDATE A
  SET A.GeogCol = B.GeogCol
  FROM TableToUpdate A
  INNER JOIN UpdatedFrom_View B
  ON  A.ID = B.ID
  WHERE A.ID BETWEEN @IDLow AND @IDHigh
END

GO

EXEC TestUpdate @IDLow = 1, @IDHigh = 1

这个查询需要半个多小时。发生了什么?

您在这里更新了多少行?我怀疑问题出在UpdateFrom_视图中。这是什么观点?@SeanLange你说“问题”是什么意思。我正在更新大约1100行。该视图包括执行一系列sql空间函数来创建一些行,然后应用UnionAggregate函数将它们转换为一个记录。它工作正常,不引用要更新的表,但它几乎完全依赖于CLR函数。内存问题很可能来自CLR函数。有时,它们可能会变得相当缺乏记忆,尤其是空间函数。奇怪的是,它已经运行了2天,只更新了150行。CLR中是否存在不可能释放对象的内容?@SeanLange。是的,内存问题肯定来自CLR。我已经意识到这个问题有一段时间了。你是说如果我运行一个查询来更新一个非CLR列,比如循环中的INT,它不会花这么长时间吗?因为只有1100行,你发布的更新通常只需要很少的时间,你几乎不会注意到它发生了。一个光标会增加一些开销,因为它必须一行一行地做,但只有1100行,它仍然是闪电般的快。