执行SQL查询需要很多时间

执行SQL查询需要很多时间,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有两张桌子。表2载有较新的记录。 表1有900K条记录,表2大致相同 执行下面的查询大约需要10分钟。表1中的大多数查询(在执行下面的查询时)都会出现超时异常 DELETE T1 FROM Table1 T1 WITH(NOLOCK) LEFT OUTER JOIN Table2 T2 ON T1.ID = T2.ID WHERE T2.ID IS NULL AND T1.ID IS NOT NULL 有人能帮我优化上面的查询或者写一些更有效的东西吗?

我有两张桌子。表2载有较新的记录。 表1有900K条记录,表2大致相同

执行下面的查询大约需要10分钟。表1中的大多数查询(在执行下面的查询时)都会出现超时异常

    DELETE T1
    FROM Table1 T1 WITH(NOLOCK)
    LEFT OUTER JOIN Table2 T2
    ON T1.ID = T2.ID
    WHERE T2.ID IS NULL AND T1.ID IS NOT NULL
有人能帮我优化上面的查询或者写一些更有效的东西吗?
另外,如何解决超时问题?

优化器可能会选择阻止整个表,因为如果需要删除那么多行,这样做更容易。在这种情况下,我会分块删除

while(1 = 1)
begin
    with cte
    as
    (
        select *
        from Table1
        where Id not in (select Id from Table2)
    )
    delete top(1000) cte

    if @@rowcount = 0
        break

    waitfor delay '00:00:01' -- give it some rest :)
end
因此,查询一次删除1000行。优化器可能只锁定一个页面来删除行,而不是整个表

此查询执行的总时间将更长,但不会阻止其他调用者

免责声明:假设为MS SQL


另一种方法是使用
快照
事务。这样,在删除行时不会阻止表读取器。

请稍等,是否正在尝试执行此操作

DELETE Table1 WHERE ID NOT IN (SELECT ID FROM Table2)
?

如果是的话,我会这样写。 您还可以尝试更新这两个表上的统计信息。当然,Table1.ID和Table2.ID上的索引可以大大加快速度

编辑:如果您从设计器获得超时,请增加SSMS中的“设计器”超时值(默认值为30秒)。工具->选项->设计器->覆盖表设计器更新的连接字符串超时值->输入合理的数字(以秒为单位)。

两个ID列都需要索引

然后使用更简单的SQL

DELETE Table1 WHERE NOT EXISTS (SELECT * FROM Table2 WHERE Table1.ID = Table2.ID)

哪个数据库引擎(SQL Server?)?表上存在哪些索引?SQL server。我是否需要在两个表中的ID列上添加索引?为什么“T1.ID不为NULL”会为false?它位于连接的左侧。如果没有索引,将有大约900k x 900k个操作。除此之外,没有真正的方法来优化您的查询。@spinning\u plate:SQL Server可以进行散列和合并联接,在这种情况下,这两种联接都比900k^2要好得多。我认为查询优化器应该能够正确地猜测嵌套循环联接不是执行此查询的最佳方式。我正在尝试在SSMS中添加索引,对于标记为“tsql”的问题,始终获得超过EDDMS SQL的锁定请求超时时间确实是一个合理的假设。)亚历克斯只是想确认一下。您确定select语句给出的结果与我的查询相同吗?我在两个表上都添加了索引。正在尝试执行您的查询。在试图选择一条记录的执行过程中,会出现超时。你知道哪里可能出错吗?@pgroke-不确定你是否知道,但可以编辑问题。问题之前没有
sql server
tsql
标记。@Andrew Venture-我假设Id不可为空。如果是这样的话,就像米奇·麦特指出的那样,不止一个条件是多余的。另一个条件将仅显示表1中存在而表2中不存在的行。所以,是的,我相信我的查询与您的查询是等价的,您可以检查它,对吗?我已经尝试运行您的查询,它需要相同的时间。表1中的大多数查询都给出了超时。我知道我做错了什么。这是一个生产数据库,所以它有很多查询是的,两个表上都有索引问题是大约有60K条记录将被删除