JOIN OR JOIN twice
Ich musste in einem JOIN zwei Tabellenspalten abfragen die beide nicht zwingend gefüllt waren.
`Email` VARCHAR(255) NULL DEFAULT NULL,
`Email2` VARCHAR(255) NULL DEFAULT NULL,
Folgender Query mit OR
war trotz Index auf den beiden Email Feldern in kTable
sehr langsam:
SELECT
s.id,
s.Email,
k.userid,
coalesce(k.Email, k.Email2) Email3
FROM sTable s
LEFT JOIN kTable k ON (s.Email = k.Email OR s.Email = k.Email2)
WHERE s.status = 1;
EXPLAIN
zeigte das alle 100000 Zeilen im "join buffer" der Tabelle kTable
noch einmal durchlaufen wurden um k.Email
oder k.Email2
zu finden. Ich gehe davon aus, dass es so langsam ist, weil der "join buffer" keinen Index enhält.
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | k | ALL | Email2 | \N | \N | \N | 103816 | Using where; Using join buffer |
Indem ich kTable
einfach zweimal JOIN
e und separat voneinander, unter Nutzung der Indizies auf den Email Feldern abfrage, konnte ich die Query-Zeit von 31,734 sec auf 0,062 sec bringen.
SELECT
s.id,
s.Email
coalesce(k1.Email, k2.Email2) Email3,
coalesce(k1.id, k2.id) userid
FROM sTable s
LEFT JOIN kTable k1 ON (s.Email = k1.Email)
LEFT JOIN kTable k2 ON (s.Email = k2.Email2)
WHERE s.status = 1
LIMIT 100;