我的查询有问题,看起来很简单,但在我的开发环境中,这会给我带来很多问题。
我要做的是通过新表中的新文章ID更改articleID。
+-----------------+ | comments | +-----------------+ | cid | articleID | +-----------------+ | 1 | 1 | +-----------------+ | 2 | 1 | +-----------------+ | 3 | 2 | +-----------------+ +------------------------+ | new_comments | +------------------------+ | comment_id | articleID | +------------------------+ | 1 | 10 | +------------------------+ | 2 | 10 | +------------------------+ | 3 | 32 | +------------------------+
我希望表“评论”的结尾如下:
+-----------------+ | comments | +-----------------+ | cid | articleID | +-----------------+ | 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;
有谁知道我有什么选择,或者我该怎么做才能阻止查询将这么多信息写入事务日志?
答案 0 :(得分: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在学术意义上是声明性的,我们有时也不会生活在学术界。 :)