Непредсказуемое поведение сервера 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, но поскольку нет фильтрации после объединения, вы получите результаты.

Другие вопросы по тегам