В чем разница между NOT EXISTS и NOT IN и LEFT JOIN, где NULL?
Мне кажется, что вы можете сделать то же самое в SQL-запросе, используя либо NOT EXISTS, NOT IN, либо LEFT JOIN, где NULL. Например:
SELECT a FROM table1 WHERE a NOT IN (SELECT a FROM table2)
SELECT a FROM table1 WHERE NOT EXISTS (SELECT * FROM table2 WHERE table1.a = table2.a)
SELECT a FROM table1 LEFT JOIN table2 ON table1.a = table2.a WHERE table1.a IS NULL
Я не уверен, если я получил все правильный синтаксис, но это общие методы, которые я видел. Почему я должен использовать один над другим? Отличается ли производительность...? Какой из них самый быстрый / самый эффективный? (Если это зависит от реализации, когда я буду использовать каждый из них?)
5 ответов:
в двух словах:
NOT INнемного по-другому: он не соответствует, если есть только одинNULLв списке.
на
MySQL,NOT EXISTS- это немного менее эффективным!--16-->на
SQL Server,LEFT JOIN / IS NULLменее эффективенна
PostgreSQL,NOT INменее эффективенна
Oracle, все три методы те же самые.
Если база данных хорошо оптимизирует запрос, два первых будут преобразованы в нечто близкое к третьему.
для простых ситуаций, подобных тем, о которых вы спрашиваете, не должно быть никакой разницы, так как все они будут выполняться как соединения. В более сложных запросах база данных может быть не в состоянии сделать соединение из
not inиnot existsqueryes. В этом случае запросы будут намного медленнее. С другой стороны, соединение может также работать плохо, если есть нет индекса, который можно использовать, поэтому только потому, что вы используете соединение, не означает, что вы в безопасности. Вам нужно будет изучить план выполнения запроса, чтобы определить, могут ли быть какие-либо проблемы с производительностью.
предполагая, что вы избегаете нулей, они все способы написания анти-вступите использование стандартного SQL.
очевидное упущение эквивалентно использованию
EXCEPT:SELECT a FROM table1 EXCEPT SELECT a FROM table2Примечание в Oracle вам нужно использовать
MINUSоператор (возможно, лучшее имя):SELECT a FROM table1 MINUS SELECT a FROM table2говоря о собственном синтаксисе, также могут быть нестандартные эквиваленты, которые стоит исследовать в зависимости от продукта, который вы используете, например
OUTER APPLYв SQL Server (что-то нравится):SELECT t1.a FROM table1 t1 OUTER APPLY ( SELECT t2.a FROM table2 t2 WHERE t2.a = t1.a ) AS dt1 WHERE dt1.a IS NULL;
когда нужно вставить данные в таблицу с многополевым первичным ключом, учтите, что это будет намного быстрее (я пробовал в Access, но думаю, что в любой базе данных), чтобы не проверять, что "не существует записей с" такими "значениями в таблице", - а просто вставить в таблицу, и лишние записи (по ключу) не будут вставлены дважды.
перспектива производительности всегда избегайте использования обратных ключевых слов, таких как NOT IN, NOT EXISTS, ... Потому что для проверки обратных элементов СУБД нужно пробежаться по всем доступным и отбросить обратную выборку.
Comments