我正在尝试在MS-SQL数据库中发现一些损坏的记录。
在一个简化的例子中,scenerio是这样的:
我有两张桌子,简单地说:
表1:Id,日期,OpId
表_2:日期,OpId,EventName
我有这个业务规则:如果Table_1中有记录,那么Table_1中的Table_1.Date和Table.OpId中应该至少有一行。
如果Table_1中有一行,并且如果表中没有与该行匹配的行,那么就会出现数据损坏 - 无论是什么原因 - 。
为了找出不正确的数据,我使用:
SELECT *
FROM table_1 t1
LEFT JOIN table_2 t2 ON t1.Date = t2.Date AND t1.OpId = t2.OpId
WHERE t2.OpId IS NULL -- So, if there is no
-- matching row in table_2 then this is a mistake
但是查询完成需要很长时间。
有没有更快或更好的方法来接近类似的场景?
答案 0 :(得分:6)
在SQL Server中执行反半连接NOT EXISTS
通常优于或等于其他选项(NOT IN
,OUTER JOIN ... NULL
,EXCEPT
)
SELECT *
FROM table_1 t1
WHERE NOT EXISTS (SELECT *
FROM table_2 t2
WHERE t1.Date = t2.Date
AND t1.OpId = t2.OpId)
见Left outer join vs NOT EXISTS。你可能会错过一个有用的索引。
答案 1 :(得分:1)
如果您使用正确的索引,则与其无关(可能会使用NOT EXISTS
而不是LEFT JOIN
会更快一点),
<强> BUT 强>
如果Table_1的数据量相对较少且没有任何FKeys或其他类似的东西,这是一次性程序,那么您可以使用这样的技巧来删除错误行:
SELECT table_1.*
INTO tempTable
FROM table_1 t1
WHERE EXISTS(SELECT * FROM table_1 t1 WHERE t1.Date = t2.Date AND t1.OpId = t2.OpId)
drop table Table_1
exec sp_rename 'tempTable', 'Table_1'
可能 更快