簡体複数の列に対してJOIN'ing、私は接点がDoNotCall電話の特定のリストに電話番号が一致するかを確認したい2つのテーブルcontacts
とdonotcall
メイクの使用
CREATE TABLE contacts
(
id int PRIMARY KEY,
phone1 varchar(20) NULL,
phone2 varchar(20) NULL,
phone3 varchar(20) NULL,
phone4 varchar(20) NULL
);
CREATE TABLE donotcall
(
list_id int NOT NULL,
phone varchar(20) NOT NULL
);
CREATE NONCLUSTERED INDEX IX_donotcall_list_phone ON donotcall
(
list_id ASC,
phone ASC
);
を持っています。 より速い検索のために、donotcall
をlist_id
とphone
に索引付けしました。
私は次のようにそれを登録しよ作る長時間かかる(例えば9秒。):
SELECT DISTINCT c.id
FROM contacts c
JOIN donotcall d
ON d.list_id = 1
AND d.phone IN (c.phone1, c.phone2, c.phone3, c.phone4)
私は別々に各電話フィールドでそれを登録しよ放置すれば一方ではるかに速く実行されます(たとえば、1.5秒):
SELECT c.id
FROM contacts c
LEFT JOIN donotcall d1
ON d1.list_id = 1
AND d1.phone = c.phone1
LEFT JOIN donotcall d2
ON d2.list_id = 1
AND d2.phone = c.phone2
LEFT JOIN donotcall d3
ON d3.list_id = 1
AND d3.phone = c.phone3
LEFT JOIN donotcall d4
ON d4.list_id = 1
AND d4.phone = c.phone4
WHERE
d1.phone IS NOT NULL
OR d2.phone IS NOT NULL
OR d3.phone IS NOT NULL
OR d4.phone IS NOT NULL
私の仮定は、それがdonotcall
にインデックスを利用していないので、最初のスニペットはゆっくり走るということです。
したがって、複数の列に対して結合を行い、インデックスを使用する方法はありますか?
実際に行う必要があるのは、データベースの構造を修正することです。 phone1、phone2、phone3、phone4 - 子テーブルが必要であることを示す必要はありません。 – HLGEM
@HLGEM:ポイントが記載されています。もし私が選択肢を持っていれば、私はそれを別の方法でやったでしょう。しかし、時には、リファクタリングを期待せずに、他の人が作成した構造に悩まされていることもあります。 – ANisus