发现 2 个表之间不匹配记录的最快方法是啥?

Posted

技术标签:

【中文标题】发现 2 个表之间不匹配记录的最快方法是啥?【英文标题】:What is the fastest way to spot un-matching records between 2 tables?发现 2 个表之间不匹配记录的最快方法是什么? 【发布时间】:2012-01-02 13:18:50 【问题描述】:

我试图在 MS-SQL 数据库中发现一些损坏的记录。

在一个简化的例子中,场景是这样的:

我有两张桌子,简单地说:

Table_1:Id、Date、OpId

Table_2:日期、OpId、事件名称

我有这个业务规则:如果 Table_1 中有记录,那么 Table_2 中至少应该存在 1 行,用于 Table_1.Date 和 Table.OpId。

如果 Table_1 中有一行,并且如果 Table_2 中没有与该行匹配的行,则存在损坏的数据 - 无论原因是什么 -。

为了找出不正确的数据,我使用:

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

但是查询完成的时间太长了。

是否有更快或更好的方法来接近类似的场景

【问题讨论】:

【参考方案1】:

在 SQL Server 中进行反半联接 NOT EXISTS 在性能上通常优于或等于其他选项(NOT INOUTER JOIN ... NULLEXCEPT

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。不过,您很可能缺少有用的索引。

【讨论】:

哇!有效!为什么这个查询要快得多? EXCEPT 和 NOT EXISTS 通常是相同的。更好的参考是explainextended.com/2009/09/15/… @gbn - EXCEPT 仅在您不需要第一个表中的其他列的情况下才有用,因此NOT EXISTS 是一个不错的默认选择。 (我确实说过“优于或等于”) @pencilCake - 另一个原因可能是此查询中的 select * 仅返回 table_1 中的列,而不是查询中的两个表。唐t use select *`. 它比 NOT EXISTS 更混乱,但它并不“更慢”,这就是我要说的......【参考方案2】:

如果您使用正确的索引,则与它无关(可能使用NOT EXISTS 而不是LEFT JOIN 会快一点),

但是

如果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'

可能更快

【讨论】:

抱歉,更改了错误的表名 那肯定是更快的 Oleg; - 我会检查马丁推荐的文章。我真的很想了解这种速度差异背后的主要原因。 它非常简单 - JOIN 必须实际查找 table1 中与 table2 中的行匹配的所有行,但 NOT EXISTS 足以找到第一个交集以最终跳过该行和其余的类似连接的搜索并前进到下一行。并且当您使用 NOT EXISTS 时,优化器会选择它想要的最佳索引,而不是 SELECT * ... LEFT JOIN,因为在 NOT EXISTS 中,它与 table2 中的特定列无关,但在 select-left 连接中 - 它确实 -那就是限制它或阻止使用匹配索引 很好的解释!谢谢! Oleg,您能否推荐我一本 TQSL 书籍,其中涵盖了有关编写 TSQL 查询和以更好的方式构建 Db 的那些类型(高级)细节?如果你知道的话。 告诉我你的 Skype ID,我会寄给你一些书来开始,继续和卡住 8-)

以上是关于发现 2 个表之间不匹配记录的最快方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 hbase 表中获取计数记录?查询记录的最快方法是啥?

MongoDB - 更新集合中所有记录的最快方法是啥?

在 C# 中将 100 000 条记录插入 MDB 文件的最快方法是啥

在python中记录实时数据的最快方法是啥,内存损失最少

SQL如何使用同一列中的值之间匹配2个表

最快的 Ruby 记录器实现是啥?