首页 > 解决方案 > 可以杀死这个 DELETE 查询吗?

问题描述

我运行了一个查询,从我的数据库中删除了大约 400 万行。在我的笔记本电脑失去网络连接之前,它运行了大约 12 个小时。那时,我决定查看数据库中查询的状态。我发现它在suspended状态。具体来说:

 Start Time               SPID  Database    Executing SQL    Status     command    wait_type        wait_time   wait_resource   last_wait_type
---------------------------------------------------------------------------------------------------------------------------------------------------
 2018/08/15 11:28:39.490  115   RingClone   *see below       suspended  DELETE     PAGEIOLATCH_EX   41          5:1:1116111     PAGEIOLATCH_EX

*这是有问题的sql查询:

DELETE FROM T_INDEXRAWDATA WHERE INDEXRAWDATAID IN (SELECT INDEXRAWDATAID FROM T_INDEX WHERE OWNERID='1486836020')

读完之后;

https://dba.stackexchange.com/questions/87066/sql-query-in-suspended-state-causing-high-cpu-usage

我意识到我可能应该把它分解成更小的部分来删除它们(或者甚至一个接一个地删除它们)。但现在我只想知道KILL这个查询对我来说是否“安全”,正如那篇文章中的答案所暗示的那样。所选答案指出的一件事是,如果在KILL执行查询时进行查询,“您可能会遇到数据一致性问题”。如果它导致我试图删除的数据出现一些问题,我并不担心。但是,我更担心这会导致其他数据或表结构本身出现一些问题。

KILL这个查询安全吗?

标签: sqlsql-server

解决方案


如果您delete通过网络从笔记本电脑运行 spid 并且它与服务器失去连接,您可以kill选择 spid 或等待它自行消失。根据@@version您的 SQL Server 实例,特别是它的修补程度,后者可能需要重新启动实例。

关于一致性问题,您似乎误解了它。仅当您在单个批处理中运行多个语句而不用事务包装时才有可能。据我了解,您只有一个声明;如果是这样的话,不要担心一致性,如果 SQL Server 很容易损坏它的数据,它就不会变成现在这样。

但是,我会重写查询,如果T_INDEX.INDEXRAWDATAID列有 NULL,那么您可能会遇到问题。最好通过 重写join,同时添加批量拆分:

while 1=1 begin

    DELETE top (10000) t
    FROM T_INDEXRAWDATA t
        inner join T_INDEX i on t.INDEXRAWDATAID = i.INDEXRAWDATAID
    WHERE i.OWNERID = '1486836020';

    if @@rowcount = 0
        break;

    checkpoint;
end;

它肯定不会变慢,但它可以提高性能,具体取决于您的架构、数据和表所具有的任何索引的状态。


推荐阅读