5

未払いの残高がある古いアカウントを持っているが、新しいアカウントを作成した人を見つけなければならないという問題があります。SSN を比較して一致させる必要があります。問題は、主要な連絡先と追加の連絡先があるため、アカウントごとに 2 つの潜在的な SSN があることです。最初はプライマリでしたが、現在はセカンダリなどであっても、一致させる必要があります。

これが私の最初の試みでした。結合と条件を下げるために今数えています。後で実際のデータを選択します。基本的に、個人用テーブルはアクティブなアカウントに一度結合され、別のコピーが延滞アカウントに結合されます。個人テーブルへの 2 つの参照は、SSN を関連付ける 4 つの可能な方法に基づいて比較されます。

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 条件で「OR」を使用することは悪い考えですか? そこで、4 つのクエリ (ssn の組み合わせごとに 1 つ) として書き直し、それらを結合してみました。これを実行するのに 30 分かかりました。

これを行うためのより良い方法はありますか、それとも、どのように行っても本当に非効率的なプロセスですか?

更新: ここでいくつかのオプションを試し、他の実験を行った後、問題を発見したと思います。当社のソフトウェア ベンダーは、データベース内の SSN を暗号化し、それらを復号化するビューを提供します。その観点から作業する必要があるため、復号化してから比較するには非常に長い時間がかかります。

4

1 に答える 1

2

個別の結合を実行してからユニオンを実行すると、問題が発生する可能性があります。同じレコード ペアが少なくとも 2 つの条件を満たしている場合はどうなるでしょうか? その場合、結果に重複があります。

最初のアプローチは実行可能だと思いますが、4 つのテーブルを結合していることを忘れないでください。それぞれのテーブルの行数が A、B、C、D の場合、RDBMS は最大で A * B * C * D レコードをチェックする必要があります。データベースに多数のレコードがある場合、これには多くの時間がかかります。

もちろん、一部の列にインデックスを追加することでクエリを最適化できます。まだインデックスが作成されていない場合は、それをお勧めします。ただし、列にインデックスを追加すると、RDBMS はそこから読み取るのは速くなりますが、そこに書き込むのは遅くなることを忘れないでください。操作が主に読み取り (選択) である場合は、列にインデックスを作成する必要がありますが、やみくもにではなく、開始する前にインデックス作成について少し勉強してください。

また、個人用、消費者用、個人用 (再び)、および uncol_acct の 4 つのテーブルを結合する場合は、次のようにします。

それぞれ t1 と t2 という名前の 2 つのサブクエリを含むクエリを作成します。最初のサブクエリは、個人と消費者を結合し、結果に t1 という名前を付けます。2 番目のクエリは、2 番目に発生した個人を uncol_acct で結合し、where 句は 2 番目の結合内にあります。前述のように、クエリには、それぞれ t1 と t2 という名前の 2 つのサブクエリが含まれます。クエリは t1 と t2 を結合します。メインクエリは有効な t1 と t2 のペアリングのみを考慮するため、このようにオプティマイズします。

また、クエリの例のように where 句が外部にある場合、4 次元結合が実行され、その後のみ where が考慮されます。これが、where 句が 2 番目のサブクエリ内にある必要がある理由です。したがって、where 句はメインの結合の前に実行されます。また、2 番目のサブクエリ内にサブクエリを作成して、条件がめったに満たされない場合に where を計算することもできます。

乾杯!

于 2013-08-15T12:55:21.703 に答える