単純化すると、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 電話の特定のリストの電話番号と一致する連絡先を確認したいと思います。検索を高速化するために、 と にインデックスを付けましdonotcall
た。list_id
phone
次の JOIN を作成すると、長い時間がかかります (例: 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)
一方、各電話フィールドで個別に LEFT JOIN を実行すると、はるかに高速に実行されます (例: 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
です。
では、複数の列に対して結合を行い、それでもインデックスを使用するにはどうすればよいでしょうか?