5

我有一个问题,我必须尝试找到拥有未结余额的旧帐户但创建了新帐户的人。我需要通过比较 SSN 来匹配它们。问题是我们有主要联系人和其他联系人,因此每个帐户有 2 个潜在的 SSN。我需要匹配它,即使它们最初是主要的,但现在是次要的等等。

这是我的第一次尝试,我现在只是在计算连接和条件。稍后我将选择实际数据。基本上,个人表一次加入活动帐户,另一个副本加入拖欠帐户。然后根据 4 种可能的 SSN 关联方式比较对个人表的两个引用。

select count(*) 
from personal pa
join consumer c 
on c.cust_nbr = pa.cust_nbr
and c.per_acct = pa.acct
join personal pu
on pu.ssn = pa.ssn
or pu.ssn = pa.addl_ssn
or pu.addl_ssn = pa.ssn
or pu.addl_ssn = pa.addl_ssn
join uncol_acct u 
on u.cust_nbr = pu.cust_nbr
and u.per_acct = pu.acct
where u.curr_bal > 0

这可行,但需要 20 分钟才能运行。我发现了这个问题在 INNER JOIN 条件中使用“或”是一个坏主意吗?所以我尝试将其重写为 4 个查询(每个 ssn 组合一个)并将它们联合起来。这需要 30 分钟才能运行。

有没有更好的方法来做到这一点,或者它只是一个非常低效的过程,不管你怎么做?

更新: 在这里玩了一些选项后,我想我发现了问题。我们的软件供应商对数据库中的 SSN 进行加密,并提供解密它们的视图。由于我必须从那个角度工作,因此需要很长时间才能解密然后进行比较。

4

1 回答 1

2

如果您运行单独的连接然后再联合,那么您可能会遇到问题。如果同一个记录对至少满足两个条件怎么办?然后,您的结果中将有重复项。

我相信您的第一种方法是可行的,但不要忘记您要加入四个表。如果各个表中的行数是 A、B、C、D,那么 RDBMS 将不得不检查最多 A * B * C * D 记录。如果您的数据库中有很多记录,那么这将花费很多时间。

当然,您可以通过向某些列添加索引来优化查询,如果它们还没有被索引,那将是一个好主意。但不要忘记,如果您为列添加索引,RDBMS 从那里读取会更快,但在那里写入会更慢。如果您的操作主要是读取(选择),那么您应该为您的列编制索引,但不要盲目地在开始做之前研究一下索引。

此外,如果您要加入四个表,personal、consumer、personal (again) 和 uncol_acct,那么您可能会执行以下操作:

编写一个查询,其中包含两个子查询,每个子查询分别命名为 t1 和 t2。第一个子查询连接个人和消费者,并将结果命名为 t1。第二个查询将使用 uncol_acct 连接第二次出现的个人,并且 where 子句将在您的第二次连接中。如前所述,您的查询将包含两个子查询,分别命名为 t1 和 t2。您的查询将连接 t1 和 t2。这样您就可以优化,因为您的主要查询将仅考虑有效 t1 和 t2 的配对。

此外,如果您的 where 子句在示例查询中位于外部,则将执行 4 维连接,并且只有在此之后才会考虑 where。这就是为什么 where 子句应该在第二个子查询中的原因,所以 where 子句将在主连接之前运行。此外,您可以在第二个子查询中创建一个子查询,以计算很少满足条件的位置。

干杯!

于 2013-08-15T12:55:21.703 回答