3

とりわけ、別のテーブルからテーブルを更新する SQL Server 2008 R2 プロジェクトを継承しました。

  • Table1(約 150,000 行) には 3 つの電話番号フィールド ( Tel1Tel2Tel3)があります。
  • Table2(約 20,000 行) には 3 つの電話番号フィールド ( Phone1Phone2Phone3)があります。

.. これらの数値のいずれかが一致した場合Table1は、更新する必要があります。

現在のコードは次のようになります。

UPDATE t1
SET surname = t2.surname, Address1=t2.Address1, DOB=t2.DOB, Tel1=t2.Phone1, Tel2=t2.Phone2, Tel3=t2.Phone3,
FROM Table1 t1 
inner join Table2 t2
on
(t1.Tel1 = t2.Phone1 and t1.Tel1 is not null) or
(t1.Tel1 = t2.Phone2 and t1.Tel1 is not null) or
(t1.Tel1 = t2.Phone3 and t1.Tel1 is not null) or
(t1.Tel2 = t2.Phone1 and t1.Tel2 is not null) or
(t1.Tel2 = t2.Phone2 and t1.Tel2 is not null) or
(t1.Tel2 = t2.Phone3 and t1.Tel2 is not null) or
(t1.Tel3 = t2.Phone1 and t1.Tel3 is not null) or
(t1.Tel3 = t2.Phone2 and t1.Tel3 is not null) or
(t1.Tel3 = t2.Phone3 and t1.Tel3 is not null);

ただし、このクエリの実行には 30 分以上かかります。

Nested Loop実行計画は、主なボトルネックがのクラスター化インデックス スキャン周辺にあることを示唆していTable1ます。両方のテーブルのID列にクラスター化インデックスがあります。

私の DBA スキルは非常に限られているため、このクエリのパフォーマンスを向上させる最善の方法を提案できる人はいますか? とのインデックスを各列に追加するのが最善でしょうかTel1、それともクエリを変更してパフォーマンスを向上させることはできますか?Tel2Tel3

4

4 に答える 4

1

まず、テーブル データを正規化します。

insert into Table1Tel 
select primaryKey, Tel1 as 'tel' from Table1 where Tel1 is not null
union select primaryKey, Tel2 from Table1 where Tel2 is not null
union select primaryKey, Tel3 from Table1 where Tel3 is not null

insert into Table2Phone 
select primaryKey, Phone1 as 'phone' from Table2 where Phone1 is not null
union select primaryKey, Phone2 from Table2 where Phone2 is not null
union select primaryKey, Phone3 from Table2 where Phone3 is not null

これらの正規化されたテーブルは、電話番号を追加の列として保存するよりもはるかに優れた方法です。

次に、テーブル全体を結合する次のようなことができます。

update t1
set surname = t2.surname, 
    Address1 = t2.Address1, 
    DOB = t2.DOB
from Table1 t1 
     inner join Table1Tel tel
         on t1.primaryKey = tel.primaryKey
     inner join Table2Phone phone
         on tel.tel = phone.phone
     inner join Table2 t2
         on phone.primaryKey = t2.primaryKey

これは、データ内の重複の根本的な問題を解決しないことに注意してください。たとえば、Joe と Jane Bloggs の両方が同じ電話番号でデータに含まれている場合 (フィールドが異なっていても)、両方のレコードが同じになるように更新されます。 .

于 2013-05-30T12:01:30.767 に答える
1

以下のクエリを試して、実行が完了するまでにかかる時間を教えてください。

UPDATE t1
SET surname = t2.surname, Address1=t2.Address1, DOB=t2.DOB, Tel1=t2.Phone1, Tel2=t2.Phone2, Tel3=t2.Phone3,
FROM Table1 t1 
inner join Table2 t2
on (
    '|'+cast(t2.Phone1 as varchar(15)+'|'+cast(t2.Phone1 as varchar(15)+'|'+cast(t2.Phone1 as varchar(15)+'|' LIKE '%|'+cast(t1.Tel1 as varchar(15)+'|%'
    or '|'+cast(t2.Phone1 as varchar(15)+'|'+cast(t2.Phone1 as varchar(15)+'|'+cast(t2.Phone1 as varchar(15)+'|' LIKE '%|'+cast(t1.Tel2 as varchar(15)+'|%'
    or '|'+cast(t2.Phone1 as varchar(15)+'|'+cast(t2.Phone1 as varchar(15)+'|'+cast(t2.Phone1 as varchar(15)+'|' LIKE '%|'+cast(t1.Tel3 as varchar(15)+'|%'
    )

3 つの OR を 1 つの LIKE に置き換えると、より高速になります。やってみなよ。

于 2013-05-30T12:02:00.260 に答える