Упрощенных, у меня есть две таблицы, contacts
и donotcall
использования Make индекса при JOIN'ing против нескольких столбцов
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
.
Когда я делаю следующее РЕГИСТРИРУЙТЕСЬ это занимает много времени (например, 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
.
Итак, как сделать присоединение к нескольким столбцам и все еще использовать индекс?
Что вам на самом деле нужно сделать, это исправить структуру данных datbase. У вас НИКОГДА не должно быть телефона1, phone2, phone3, phone4 - это означает, что вам нужен детский стол. – HLGEM
@ HLGEM: Точка отмечена. Я бы сделал это по-другому, если бы у меня был выбор. Но иногда вы застряли со структурой, которую создали другие, без надежды на рефакторинг. – ANisus