Непредсказуемое поведение сервера MySQL при левом соединении
CREATE TEMPORARY TABLE tmp_userid
(
uUserId int unsigned NOT NULL PRIMARY KEY
) ENGINE='MEMORY';
CREATE TEMPORARY TABLE tmp_studentid
(
uClassId INT UNSIGNED NOT NULL,
uUserId int unsigned NOT NULL,
PRIMARY KEY(uClassId,uUserId)
) ENGINE='MEMORY';
INSERT INTO tmp_userid
values (18);
INSERT INTO tmp_studentid
values (1,1),
(1,3),
(2,15),
(3,20),
(3,25),
(4,35),
(4,45)
;
Теперь, если я попытаюсь выполнить:
SELECT * FROM tmp_userid U
LEFT JOIN tmp_studentid S ON U.uUserId = S.uUserId
where uClassId = 4;
SELECT * FROM tmp_userid U
LEFT JOIN tmp_studentid S ON U.uUserId = S.uUserId AND uClassId = 4;
возвращает другой результат!
Кто-нибудь может объяснить это поведение?
Спасибо
1 ответ
Решение
Если вы проверите планы выполнения с EXPLAIN
вы увидите, что первый запрос имеет Impossible WHERE noticed after reading const tables
, Вот и все - mysql сначала выполняет JOINs, а затем фильтрует результат. Поскольку ни одна выходная строка объединения не соответствует вашему фильтру, вы получите пустой конечный результат.
Второй запрос выполняет OUTER JOIN с условием, которое всегда ложно, возвращая NULL для uClassId
а также uUserId
, но поскольку нет фильтрации после объединения, вы получите результаты.