Sql 获取两个几乎相同的表之间的记录差异
我有一个将40多个相同结构的数据库合并为一个合并数据库的过程,唯一的区别是合并数据库向每个表添加一个project_id字段 为了尽可能地提高效率,我尝试只将已添加/更改的记录从源数据库复制/更新到合并数据库。我从合并数据库中删除过时的记录,然后复制任何不存在的记录。要删除过期/更改的记录,我将使用类似于以下内容的查询:Sql 获取两个几乎相同的表之间的记录差异,sql,performance,not-exists,Sql,Performance,Not Exists,我有一个将40多个相同结构的数据库合并为一个合并数据库的过程,唯一的区别是合并数据库向每个表添加一个project_id字段 为了尽可能地提高效率,我尝试只将已添加/更改的记录从源数据库复制/更新到合并数据库。我从合并数据库中删除过时的记录,然后复制任何不存在的记录。要删除过期/更改的记录,我将使用类似于以下内容的查询: DELETE FROM <table> WHERE NOT EXISTS (SELECT <primary keys>
DELETE FROM <table>
WHERE NOT EXISTS (SELECT <primary keys>
FROM <source> b
WHERE ((<b.fields = a.fields>) or
(b.fields is null and a.fields is null)))
AND PROJECT_ID = <project_id>
这在很大程度上是可行的,但是源数据库中的一个表有超过700000条记录,并且这个查询需要一个多小时才能完成
如何使此查询更高效?使用时间戳或更好的审计表来识别自时间X以来更改的记录,然后在上次同步启动时保存时间X。我们将其用于接口提要。您可能希望尝试使用空筛选器进行左连接:
DELETE <table>
FROM <table> t
LEFT JOIN <source> b
ON (t.Field1 = b.Field1 OR (t.Field1 IS NULL AND b.Field1 IS NULL))
AND(t.Field2 = b.Field2 OR (t.Field2 IS NULL AND b.Field2 IS NULL))
--//...
WHERE t.PROJECT_ID = <project_id>
AND b.PrimaryKey IS NULL --// any of the PK fields will do, but I really hope you do not use composite PKs
但是如果您比较所有非PK列,那么您的查询将受到影响
在这种情况下,最好按照DVK的建议在两个数据库上都添加UpdatedAt TIMESTAMP字段,您可以使用AFTER update触发器进行更新,这样您的同步过程会快得多,因为您创建了一个包含PKs和UpdatedAt列的索引。您可以对WHERE语句重新排序;它有四个比较,把最有可能失败的一个放在第一位
如果您可以稍微更改数据库/应用程序,并且需要再次更改,那么添加一个表示已更新的位字段可能不是一个好的选择。我通常会重写这样的查询,以避免。。。 不存在对性能来说是可怕的,尽管不存在对这方面的改进 看看这篇文章 我的建议 在工作/临时表中选择pkey列,添加列标志int default 0 not null,并为pkey列编制索引。如果子查询中存在记录,则标记标志=1!快得多!。 将主查询中的子选择替换为exists where select pkey from TENTABLE where flag=0 这样做的结果是能够创建一个“不存在”值列表,这些值可以从一个全包集合中包含使用 这是我们的全套。 {1,2,3,4,5} 这是现有的一套 {1,3,4} 我们从这两个集合中创建工作表,从技术上讲是一个左外连接 记录:存在 {1:1,2:0,3:1,4:1,5:0} 我们的一组“不存在的记录” {2,5}从其中选择*标志=0 我们的产品。。。还有更快的索引 {1,2,3,4,5}在{2,5}={2,5} {1,2,3,4,5}不在{1,3,4}={2,5} 这可以在没有工作台的情况下完成,但它的使用使得可视化正在发生的事情变得更容易
Kris您有字段索引吗?这些是您添加到数据库/表中的内容吗?IE:在每个表中添加一个last_updated字段,在每个数据库中添加一个audit_表?不幸的是,我无法修改源数据库的架构,因为它们来自供应商产品。从技术上讲,我可以向每个表添加一个审核表,甚至一个字段作为时间戳,但供应商流程永远不会向审核表添加任何内容,也不会在更改时填充时间戳字段。该表是否具有非递减字段?DB生成的或自然发生的ID?如果没有,可以通过定期运行的SP来填充审计表,但是非常讨厌。此外,请查看是否可以以某种方式非正式地插入供应商流程。例如,可能在某个文件系统或数据库中有一些剩余的淤泥,这些文件系统或数据库列出了5分钟前刚刚或自5分钟前开始执行的行。