简体   繁体   English

执行 SQL 查询需要很多时间

[英]To execute SQL query takes a lot of time

I have two tables.我有两张桌子。 Tables 2 contains more recent records.表 2 包含最近的记录。 Table 1 has 900K records and Table 2 about the same.表 1 有 900K 记录,表 2 大致相同。

To execute the query below takes about 10 mins.执行下面的查询大约需要 10 分钟。 Most of the queries (at the time of execution the query below) to table 1 give timeout exception.对表 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

Could someone help me to optimize the query above or write something more efficient?有人可以帮我优化上面的查询或写一些更有效的东西吗? Also how to fix the problem with time out issue?另外如何解决超时问题?

Optimizer will likely chose to block whole table as it is easier to do if it needs to delete that many rows.优化器可能会选择阻止整个表,因为如果它需要删除那么多行,这样做更容易。 In the case like this I delete in chunks.在这种情况下,我会分块删除。

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

So the query deletes 1000 rows at a time.所以查询一次删除 1000 行。 Optimizer will likely lock just a page to delete the rows, not whole table.优化器可能会只锁定一个页面来删除行,而不是整个表。

The total time of this query execution will be longer, but it will not block other callers.此查询执行的总时间会更长,但不会阻塞其他调用者。

Disclaimer: assumed MS SQL.免责声明:假定 MS SQL。

Another approach is to use SNAPSHOT transaction.另一种方法是使用SNAPSHOT事务。 This way table readers will not be blocked while rows are being deleted.这样在删除行时不会阻塞表读取器。

Wait a second, are you trying to do this...等一下,你是不是要这么做……

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

? ?

If so, that's how I would write it.如果是这样,我会这样写。 You could also try to update the statistics on both tables.您还可以尝试更新两个表的统计信息。 And of course indexes on Table1.ID and Table2.ID could speed things up considerably.当然,Table1.ID 和 Table2.ID 上的索引可以大大加快速度。

EDIT: If you're getting timeouts from the designer, increase the "Designer" timeout value in SSMS (default is 30 seconds).编辑:如果您从设计器那里获得超时,请增加 SSMS 中的“设计器”超时值(默认为 30 秒)。 Tools -> Options -> Designers -> "Override connection string time-out value for table designer updates" -> enter reasonable number (in seconds).工具 -> 选项 -> 设计器 -> “覆盖表设计器更新的连接字符串超时值” -> 输入合理的数字(以秒为单位)。

Both ID columns need an index两个 ID 列都需要索引

Then use simpler SQL然后使用更简单的 SQL

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM