Мне кажется, что вы можете сделать то же самое в запросе SQL, используя NOT EXISTS, NOT IN или LEFT JOIN WHERE 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
Я не уверен, что я правильно понял весь синтаксис, но это общие приемы, которые я видел. Почему я решил бы использовать один поверх другого? Отличается ли производительность ...? Какой из них самый быстрый / самый эффективный? (Если это зависит от реализации, когда я буду использовать каждый из них?)
EXISTS
предложении. Вы можете вернуться*
,NULL
или как угодно: все это будет оптимизировано.SELECT
иFROM
. И*
просто легче набрать. Да,SQL
имеет некоторое сходство с естественным языком, но он анализируется и выполняется машиной, запрограммированной машиной. Дело не в том, что он когда-нибудь внезапно взорвется в вашей кабинке и закричит: «Прекратите требовать дополнительные поля вEXISTS
запросе, потому что мне надоело их анализировать, а затем отбрасывать!». Все нормально с компьютером, правда.Ответы:
NOT IN против NOT EXISTS vs. LEFT JOIN / IS NULL: SQL Server
NOT IN против NOT EXISTS vs. LEFT JOIN / IS NULL: PostgreSQL
НЕ В, против НЕ СУЩЕСТВУЕТ, ПРОТИВ ЛЕВНОГО СОЕДИНЕНИЯ / НУЛЬ: Oracle
НЕ В, против НЕ СУЩЕСТВУЕТ, ПРОТИВ ЛЕВОГО СОЕДИНЕНИЯ / НУЛЬ: MySQL
В двух словах:
NOT IN
немного отличается: он никогда не совпадает, еслиNULL
в списке есть только один .В
MySQL
,NOT EXISTS
немного менее эффективнымВ
SQL Server
,LEFT JOIN / IS NULL
менее эффективенВ
PostgreSQL
,NOT IN
менее эффективенВ
Oracle
, все три метода одинаковы.источник
table1 .a
содержит запрос не возвратит эту строку , но и сделает запрос , если пусто. НЕ ВНУТРИ против НЕ СУЩЕСТВУЕТ Обнуляемые столбцы: SQL ServerNULL
EXISTS
NOT IN
table2
NULL NOT IN ()
оценивается как истинное (неNULL
), так же какNOT EXISTS (NULL = column)
NOT EXISTS
Всегда будет возвращать строку , ноNOT IN
будет делать это только если суб - запрос не возвращает ни одной строки.Если база данных хороша для оптимизации запроса, два первых будут преобразованы во что-то близкое к третьему.
Для простых ситуаций, подобных тем, о которых вы спрашиваете, различий не должно быть или почти не должно быть, поскольку все они будут выполняться как объединения. В более сложных запросах, база данных может быть не в состоянии сделать присоединиться из ряда
not in
иnot exists
queryes. В этом случае запросы станут намного медленнее. С другой стороны, объединение может также работать плохо, если нет индекса, который можно использовать, так что если вы используете объединение, это еще не значит, что вы в безопасности. Вам нужно будет изучить план выполнения запроса, чтобы определить, есть ли проблемы с производительностью.источник
Предполагая, что вы избегаете пустых значений, все они являются способами написания анти-объединения с использованием стандартного SQL.
Очевидным упущением является эквивалент использования
EXCEPT
:Обратите внимание, что в Oracle вам нужно использовать
MINUS
оператор (возможно, лучшее имя):Говоря о проприетарном синтаксисе, могут быть и нестандартные эквиваленты, которые стоит изучить в зависимости от продукта, который вы используете, например,
OUTER APPLY
в SQL Server (что-то вроде):источник
Когда нужно вставить данные в таблицу с многопольным первичным ключом, учтите, что будет гораздо быстрее (я пытался в Access, но я думаю, в любой базе данных) не проверять, что «не существует записей с« такими »значениями в таблице», - скорее просто вставьте в таблицу, и лишние записи (по ключу) не будут вставлены дважды.
источник
С точки зрения производительности всегда избегайте использования обратных ключевых слов, таких как NOT IN, NOT EXISTS, ... Потому что для проверки обратных элементов СУБД необходимо просмотреть все доступные и отбросить обратный выбор.
источник
NOT
?