[英]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.