2009-10-05 55 views
0

我有一个将40个以上相同结构的数据库合并到一个统一数据库的过程,唯一的区别是统一数据库向每个表添加了一个project_id字段。获取2个几乎相同的表之间的记录差异

为了尽可能地提高效率,我试着只将源数据库中的记录复制/更新到统一数据库,如果它已被添加/更改。我从统一数据库中删除过期的记录,然后复制任何不存在的记录。要删除过时的/更改的记录,我用类似这样的查询:

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> 

这适用于大多数情况,但在源数据库中的一个表有超过70万的记录,此查询接管的小时完成。

如何使此查询更有效?

+0

你有一个索引*字段*? – 2009-10-05 18:46:49

回答

2

使用时间戳或更好的审计表来识别自时间“X”以来更改的记录,然后在上次同步开始时保存时间“X”。我们将它用于接口提要。

+0

这些东西是你添加到数据库/表中的吗? IE:为每个表添加last_updated字段,并为每个数据库添加一个audit_table?不幸的是,我无法修改源数据库的模式,因为它们来自供应商产品。 – aasukisuki 2009-10-05 18:49:16

+0

你可以添加一个审计表吗? – DVK 2009-10-05 18:59:07

+0

从技术上讲,我可以为每个表添加审计表或字段以用作时间戳,但供应商进程决不会向审计表添加任何内容,或者在更改时填充时间戳字段。 – aasukisuki 2009-10-05 19:24:49

0

你可能想尝试LEFT JOIN与空滤器:

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列,那么您的查询是要受到影响。

在这种情况下,最好在两个数据库中添加一个UpdatedAt TIMESTAMP字段(如DVK建议),您可以使用AFTER UPDATE触发器更新,那么同步过程会更快,因为您创建了一个索引PKs和UpdatedAt列。

0

您可以重新排列WHERE语句;它有四个比较,把最有可能首先失败的比较。

如果您可以稍微改变数据库/应用程序,并且需要再次执行此操作,则说明“已更新”的位字段可能不是一个不好的附加项。

0

我通常会重写像这样的查询以避免不... Not In对于性能来说太糟糕了,尽管Not Exists在这方面有所改进。

看看这篇文章,http://www.sql-server-pro.com/sql-where-clause-optimization.html

我的建议......

选择你的p键列到工作/临时表,添加一列(标志)整数默认0不为空,且指数pkey列。如果记录存在于子查询中,则标记标志= 1(更快!)。 取代你的主查询中的子选择与存在的地方(选择pkey from temptable 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}

这可以在没有工作表的情况下完成,但是它的使用使得可视化更容易发生。

克里斯