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 JOINe 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;