当前位置:  开发笔记 > 编程语言 > 正文

如果我停止长时间运行的查询,它会回滚吗?

如何解决《如果我停止长时间运行的查询,它会回滚吗?》经验,为你挑选了2个好方法。

用于遍历1700万条记录以删除重复项的查询 现在已经运行了大约16个小时,我想知道如果查询现在已经停止,如果它将完成删除语句,或者如果它在运行时已经删除了查询?事实上,如果我确实停止它,它是否最终确定删除或回滚?

我发现当我做的时候

 select count(*) from myTable

它返回的行(在执行此查询时)比起始行计数少约5.显然服务器资源非常差,所以这意味着这个过程需要16个小时才能找到5个重复项(实际上有数千个),这可能会运行数天?

这个查询在2000行测试数据上花费了6秒钟,并且它在这组数据上运行良好,所以我认为整套需要15个小时.

有任何想法吗?

以下是查询:

--Declare the looping variable
DECLARE @LoopVar char(10)


    DECLARE
     --Set private variables that will be used throughout
      @long DECIMAL,
      @lat DECIMAL,
      @phoneNumber char(10),
      @businessname varchar(64),
      @winner char(10)

    SET @LoopVar = (SELECT MIN(RecordID) FROM MyTable)

    WHILE @LoopVar is not null
    BEGIN

      --initialize the private variables (essentially this is a .ctor)
      SELECT 
        @long = null,
        @lat = null,
        @businessname = null,
        @phoneNumber = null,
        @winner = null

      -- load data from the row declared when setting @LoopVar  
      SELECT
        @long = longitude,
        @lat = latitude,
        @businessname = BusinessName,
        @phoneNumber = Phone
      FROM MyTable
      WHERE RecordID = @LoopVar

      --find the winning row with that data. The winning row means 
      SELECT top 1 @Winner = RecordID
      FROM MyTable
      WHERE @long = longitude
        AND @lat = latitude
        AND @businessname = BusinessName
        AND @phoneNumber = Phone
      ORDER BY
        CASE WHEN webAddress is not null THEN 1 ELSE 2 END,
        CASE WHEN caption1 is not null THEN 1 ELSE 2 END,
        CASE WHEN caption2 is not null THEN 1 ELSE 2 END,
        RecordID

      --delete any losers.
      DELETE FROM MyTable
      WHERE @long = longitude
        AND @lat = latitude
        AND @businessname = BusinessName
        AND @phoneNumber = Phone
        AND @winner != RecordID

      -- prep the next loop value to go ahead and perform the next duplicate query.
      SET @LoopVar = (SELECT MIN(RecordID) 
    FROM MyTable
    WHERE @LoopVar < RecordID)
    END

小智.. 28

不,如果停止查询执行,sql server将不会回滚它已经执行的删除.oracle需要显式提交操作查询或数据被回滚,但不是mssql.

使用sql server它将不会回滚,除非您在事务的上下文中专门运行并且回滚该事务,或者在没有提交事务的情况下关闭连接.但我在上面的查询中没有看到事务上下文.

您也可以尝试重新构建查询以使删除效率更高一些,但基本上如果您的盒子的规格不符合要求,那么您可能会被迫等待它.

今后,您应该在桌面上创建一个独特的索引,以避免再次经历这个问题.



1> 小智..:

不,如果停止查询执行,sql server将不会回滚它已经执行的删除.oracle需要显式提交操作查询或数据被回滚,但不是mssql.

使用sql server它将不会回滚,除非您在事务的上下文中专门运行并且回滚该事务,或者在没有提交事务的情况下关闭连接.但我在上面的查询中没有看到事务上下文.

您也可以尝试重新构建查询以使删除效率更高一些,但基本上如果您的盒子的规格不符合要求,那么您可能会被迫等待它.

今后,您应该在桌面上创建一个独特的索引,以避免再次经历这个问题.



2> jwanagel..:

您的查询未包含在事务中,因此它不会回滚各个删除语句已经进行的更改.

我使用以下查询在我自己的SQL Server上自己测试了这个,并且即使我取消了查询,ApplicationLog表也是空的:

declare @count int
select @count = 5
WHILE @count > 0
BEGIN
  print @count
  delete from applicationlog;
  waitfor time '20:00';
  select @count = @count -1
END

但是,您的查询可能需要数天或数周,甚至超过15小时.您估计每6秒处理2000条记录的错误是错误的,因为while循环中的每次迭代将花费1700万行显着更长的时间,而2000条行则需要更长的时间.因此,除非您的查询在2000行中花费的时间少于一秒,否则所有1700万行需要几天.

您应该问一个关于如何有效删除重复行的新问题.


爱德华多,你错了.我在回答之前专门测试了这个.Delete语句绝对保持提交.while循环不会在内部语句周围创建任何类型的显式事务.
不,即使语句在存储过程中,结果也是相同的.我刚刚对此进行了测试以确认.
推荐阅读
殉情放开那只小兔子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有