Как часть процесса замены старого кода, который использовал невероятно медленный вложенный выбор, я получил запрос, который выглядит так:
SELECT r3.r_id AS r3_id, r2.r_id AS r2_id, r1.r_id AS r1_id
FROM
table_r r3
LEFT JOIN (
table_r r2
INNER JOIN (
table_r r1
INNER JOIN table_d d ON r1.r_id = d.r_id
) ON r2.r_id = r1.parent_id
) ON r3.r_id = r2.r_id
WHERE d.d_id = 3
Итак, в самом внутреннем соединении я ищу записи в table_r
(copy r1
), которые имеют отношение к подмножеству записей из table_d
.
В следующем объединении я ищу записи во второй копии table_r
(r2
), основной индекс (r_id
) соответствует родительскому индексу (parent_id
) записей из предыдущее соединение.
Затем я пытаюсь сделать LEFT JOIN
с третьей копией table_r
(r3
), просто сопоставив r_id
с r_id
предыдущего соединения. Идея этого внешнего соединения состоит в том, чтобы получить ВСЕ записи из table_r
, но затем сделать эквивалент выбора NOT IN
, используя еще одно условие (еще не в моем запросе), чтобы определить, какие записи в r3
имеют NULLs
для r2_id
.
Проблема в том, что LEFT JOIN
не дает мне всего table_r
. Это дает мне тот же набор записей, который я получаю без финального соединения, другими словами, то же самое, что и INNER JOIN
. Поэтому, когда я ожидаю 1208 записей, я получаю 508.
Я знаю, что, должно быть, я здесь делаю что-то здесь...
Что произойдет, если вы попробуете это?
SELECT r3.r_id AS r3_id, r2.r_id AS r2_id, r1.r_id AS r1_id
FROM
table_r r3
LEFT JOIN (
table_r r2
INNER JOIN (
table_r r1
INNER JOIN table_d d ON r1.r_id = d.r_id AND d.d_id = 3
) ON r2.r_id = r1.parent_id
) ON r3.r_id = r2.r_id
Что я сделал, был перемещен d.d_id = 3 из предложения where в квалификаторы INNER JOINs ON.