删除不在查询中的位置

时间:2010-06-15 17:38:11

标签: sql database tsql sql-delete

我有一个查找表(##lookup)。我知道这是糟糕的设计,因为我正在复制数据,但它极大地加快了我的查询速度。我有一个填充此表的查询

insert into ##lookup select distinct col1,col2,... from table1...join...etc...

我想模拟这种行为:

delete from ##lookup
insert into ##lookup select distinct col1,col2,... from table1...join...etc...

这样可以正确地更新表格。但这是很多插入和删除。它与我的索引混淆并锁定表格以供选择。

此表也可以通过以下内容进行更新:

delete from ##lookup where not in (select distinct col1,col2,... from table1...join...etc...)
insert into ##lookup (select distinct col1,col2,... from table1...join...etc...) except if it is already in the table

第二种方式可能需要更长时间,但我可以说“没有锁定”,我可以从表格中选择。

关于如何以第二种方式编写查询的任何想法?

2 个答案:

答案 0 :(得分:2)

DELETE LU
FROM ##lookup LU
LEFT OUTER JOIN Table1 T1 ON T1.my_pk = LU.my_pk
WHERE T1.my_pk IS NULL

INSERT INTO ##lookup (my_pk, col1, col2...)
SELECT T1.my_pk, T1.col1, T1.col2...
FROM Table1 T1
LEFT OUTER JOIN ##lookup LU ON LU.my_pk = T1.my_pk
WHERE LU.my_pk IS NULL

您也可以使用WHERE NOT EXISTS而不是上面的LEFT JOIN来查找行的不存在。

如果您使用的是SQL 2008,您可能还需要查看MERGE语句。否则,您不会保持表同步 - 您只是保持PK同步。如果其中一个列在一个表中更改,而另一个表中的列不会在上面反映。

无论哪种方式,听起来您可能都想考虑优化查询。虽然复制数据可能看起来像是一个很好的修复你的性能问题,你可以看到它可以带来很多麻烦(这只是一个)。你最好找到表现不佳的根本原因并修复它而不是戴上这个丑陋的绑带。

答案 1 :(得分:0)

所有DELETE都会被记录下来,如果你的计划是核对整个表,它会杀死性能。根据您正在处理的行数,您可以使用未记录的TRUNCATE。

您的SELECT语句需要多长时间?如果选择花费少量时间并且您没有经常运行它,您可以尝试这样的事情。

选择不同的... INTO#tempTable1 来自table1 ...加入...等...

开始交易 drop table ## lookup 从#tempTable1中选择*到## lookup 提交交易

汤姆的回答可能是最强大的,但我只是觉得我会选择一些替代方案。不知道为什么全局临时表与真实表相比是必要的,但是