2010-02-01 50 views
3

在Sql Server 2008上,我有一个运行缓慢的更新查询,这个查询已经工作了3个小时。有没有什么办法可以得到关于这个执行的任何统计信息(比如说到目前为止有多少行已经改变了,或者其他什么)?(当然,在执行时)?这样我就可以在取消查询和优化或让它完成之间做出决定。获取有关运行更新查询的信息

否则,我应该在执行前做了什么吗?如果是这样,那么在执行之前可以做些什么来获取有关正在运行的更新查询的信息。 (当然,在不影响性能很大程度上)

澄清的更新:
在问题中提到的更新语句是(例如):
UPDATE myTable的SET为col_a = 'VALUE1' WHERE col_B = '值'
换句话说,它是一个单一查询,更新整个表

回答

3

你能怎么做呢?

您可以尝试使用WITH(NOLOCK)table hint运行单独的查询来查看已更新了多少行。 例如如果更新语句是:

UPDATE MyTable 
SET MyField = 'UPDATEDVALUE' 
WHERE ID BETWEEN 1 AND 10000000 

你可以运行这个命令:

SELECT COUNT(*) 
FROM MyTable WITH (NOLOCK) 
WHERE ID BETWEEN 1 AND 10000000 
    AND MyField = 'UPDATEDVALUE' 


你能在将来做什么?

你可以批量更新,并输出进度。例如使用一个循环来更新1000中说明的块的记录(解释点的任意值)。在每个更新块完成后,打印出进度(假设你正在从SSMS运行)例如

DECLARE @RowCount INTEGER 
SET @RowCount = 1 
DECLARE @Message VARCHAR(500) 
DECLARE @TotalRowsUpdated INTEGER 
SET @TotalRowsUpdated = 0 

WHILE (@RowCount > 0) 
    BEGIN 
     UPDATE TOP (1000) MyTable 
     SET MyField = 'UPDATEDVALUE' 
     WHERE ID BETWEEN 1 AND 10000000 
       AND MyField <> 'UPDATEDVALUE' 

     SELECT @RowCount = @@ROWCOUNT 
     SET @TotalRowsUpdated = @TotalRowsUpdated + @RowCount 
     SELECT @Message = CAST(GETDATE() AS VARCHAR) + ' : ' + CAST(@TotalRowsUpdated AS VARCHAR) + ' records updated in total' 
     RAISERROR (@Message, 0, 1) WITH NOWAIT 
    END 

这样使用RAISERROR可以确保立即打印出进度信息。如果您使用PRINT,则会将邮件假脱机并不立即输出,因此您无法看到实时进度。

+0

表提示WITH(NOLOCK)为我工作。由于我是sql server上的初学者,所以我不知道这一点,所以在另一个运行时我无法执行单独的查询。非常感谢你。顺便说一下,我对第二种解决方案有疑问。如果ID和MyField不是索引列,while循环的运行速度是否比单个更新查询慢?也就是说,例如,在第五回合中,它是否扫描4000行的表以找出MyField <>'UPDATEDVALUE'或缓存使它像单个更新查询一样快速? – Ahmet 2010-02-02 05:29:08

0

如果您发布查询以便我们可以查看并尝试帮助您,它确实会帮助我们。 查看发生了什么的一种方法是使用SQL事件探查器来分析更新/插入。

1

http://www.sqlnewsgroups.net/group/microsoft.public.sqlserver.server/topic19776.aspx

“你应该能够做到脏读产生行 满足UPDATE子句的行数(假设值尚未使用)。”

如果您将查询设置为使用“READ UNCOMMITTED”,则应该能够通过具有适当条件的select语句查看由语句更新的行。我不是这方面的专家......所以只是我的猜测。

+0

只是为了知识:在做了一点研究之后,我发现'READ UNCOMMITTED'和'WITH(NOLOCK)'(由AdaTheDev建议)做同样的事情,除了第二个只针对有关的查询,而另一个一般设置。不管怎么说,还是要谢谢你。 – Ahmet 2010-02-02 11:17:04

0

不知道你在做什么,我不能肯定地说,但是如果你把更新放在一个过程中,那么使用PRINT命令在特定步骤输出状态更新,这些消息在过程运行期间输出时间在结果选项卡旁边的消息选项卡中。