0

我有一个看起来很简单的查询的问题,但它在我的开发环境中给我带来了很多问题。

我要做的是通过我在新表中的新文章 ID 更改文章 ID。

+-----------------+
| 评论 |
+-----------------+
| 西德 | 文章ID |
+-----------------+
| 1 | 1 |
+-----------------+
| 2 | 1 |
+-----------------+
| 3 | 2 |
+-----------------+

+------------------------+
| 新评论 |
+------------------------+
| 评论 ID | 文章ID |
+------------------------+
| 1 | 10 |
+------------------------+
| 2 | 10 |
+------------------------+
| 3 | 32 |
+------------------------+

我希望表格“评论”的结尾如下:

+-----------------+
| 评论 |
+-----------------+
| 西德 | 文章ID |
+-----------------+
| 1 | 10 |
+-----------------+
| 2 | 10 |
+-----------------+
| 3 | 32 |
+-----------------+

所以我执行这个查询:

UPDATE comments SET comments.articleID = new_comments.articleID_new
FROM comments INNER JOIN new_comments
ON comments.cid = new_comments.comment_id;

问题是我在磁盘中有 20GB 的可用空间,当我执行此查询时,事务日志开始增长并在查询完成之前使用所有可用空间。6 分钟后,磁盘的 20GB 可用空间就消失了。

我已将恢复模式更改为简单。但是,问题仍然存在,并且事务日志不断增长。

我可以使用我在 stackoverflow 中看到的下一个查询看到数据库的事务日志正在增长:

SELECT (size * 8.0)/1024.0 AS size_in_mb,
CASE
    WHEN max_size  = -1 THEN 9999999 -- Unlimited growth, so handle this how you want
    ELSE (max_size * 8.0)/1024.0
END AS max_size_in_mb
FROM MyDatabase.sys.database_files
WHERE data_space_id = 0;

有谁知道我有什么选择或者我可以做些什么来阻止查询将这么多的信息写入事务日志?

4

1 回答 1

0

尝试这样的事情:

declare @batchSize int 10000;
while(1=1)
begin
UPDATE top(@batchSize) comments SET comments.articleID = new_comments.articleID_new
FROM comments INNER JOIN new_comments
ON comments.cid = new_comments.comment_id
where comments.articleID != new_comments.articleID_new;
if (@@rowcount < @batchSize)
   break
end

这将一次运行更新 1000 行,直到更新完成。与往常一样,首先在测试系统中运行它,但这应该可以解决问题。

现在,至于您遇到这种情况的原因,数据库需要能够回滚事务直到它提交。所以,如果你试图在一个事务中修改太多数据,你会填满你的日志。因此,尽管 SQL 在学术意义上是声明性的,但有时我们并不生活在学术世界中。:)

于 2014-01-08T21:42:39.613 回答