Почему INNER JOIN не равно (! =) Вечно вешать
Когда я выполняю следующий запрос:
SELECT * FROM `table1`
INNER JOIN table2 ON table2.number = table1.number
Я получаю результат в течение 2 секунд. В table2
имеется около 6 миллионов записей и 1 миллион записей в table1
table2.number
и table1.number
индексируются.
Теперь я хочу получить список номеров, которые не существуют. Вот так:
SELECT * FROM `table1`
INNER JOIN table2 ON table2.number != table1.number
Это навсегда и по-прежнему висит.. Как исправить?
Ответы
Ответ 1
Скажем, ваш первый INNER JOIN
возвращает 75% из 1 000 000 строк в table1
. Второй запрос не возвращает 250 000 других строк, как вы думаете. Вместо этого он пытается создать декартово произведение и удалить 750 000 совпадающих строк. Таким образом, он пытается вернуть 6 000 000 и раз, 1 000 000-750 000 строк. То, что выровняно 6 и times; 10 12 набор результатов.
Вероятно, вы хотите:
SELECT * FROM table1
LEFT JOIN table2 ON table2.number = table1.number
WHERE table2.number IS NULL
Это возвращает строки в table1
, отсутствующие в table2
.
Вы также можете быть заинтересованы в FULL OUTER JOIN
:
SELECT * FROM table1
FULL OUTER JOIN table2 ON table2.number = table1.number
WHERE table1.number IS NULL AND table2.number IS NULL
Это возвращает строки в обеих таблицах, которые не имеют соответствия в другой таблице.
Ответ 2
Причина, по которой это не работает, - это то, что вы базово присоединяете каждую строку таблицы1 к каждой строке с таблицей 2. Вам нужно что-то еще, чтобы присоединиться к ней. Лучший способ сделать это - сделать левое соединение (подразумевая, что он присоединится к таблице1 независимо от того, что, но не table2), а затем проверьте, чтобы не было записи для таблицы2 с нулевым значением. Затем вам нужно будет сделать то же самое для таблицы2.
SELECT * FROM `table1`
LEFT JOIN table2 ON table2.number = table1.number
WHERE table2.number is NULL
UNION
SELECT * FROM `table2`
LEFT JOIN table1 ON table2.number = table1.number
WHERE table1.number is NULL
Ответ 3
Вместо этого вы можете использовать этот метод:
SELECT * FROM table1
LEFT JOIN table2 ON table2.number = table1.number
WHERE table2.number равно NULL ИЛИ table1.number равно NULL