Simplified, ich habe zwei Tabellen, contacts
und donotcall
Nutzen Sie Index, wenn JOIN'ing gegen mehrere Spalten
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
);
Ich mag würde, um zu sehen, was Kontakte entspricht der Telefonnummer in einer bestimmten Liste von DoNotCall Telefon. Für schnellere Suche, habe ich donotcall
auf list_id
und phone
indiziert.
Wenn ich machen folgende JOIN es eine lange Zeit in Anspruch nimmt (zB 9 Sekunden.):
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)
Während, wenn ich auf jedem Telefonfeld es separat LEFT JOIN läuft viel schneller (z. B. 1,5 Sekunden):
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
Meine Vermutung ist, dass der erste Schnipsel langsam läuft, weil es nicht den Index auf donotcall
nicht nutzen.
Also, wie ein Join zu mehreren Spalten zu tun und immer noch den Index verwenden?
Was Sie eigentlich tun müssen, ist Ihre Datenbankstruktur zu reparieren. Du solltest NIEMALS über phone1, phone2, phone3, phone4 verfügen - das bedeutet, dass du eine untergeordnete Tabelle benötigst. – HLGEM
@HLGEM: Punkt notiert. Ich hätte es auch anders gemacht, wenn ich die Wahl hätte. Aber manchmal steckt man in einer Struktur, die andere geschaffen haben, ohne Hoffnungen auf Refactoring. – ANisus