В чем разница между 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


Я не уверен, если я получил все правильный синтаксис, но это общие методы, которые я видел. Почему я должен использовать один над другим? Отличается ли производительность...? Какой из них самый быстрый / самый эффективный? (Если это зависит от реализации, когда я буду использовать каждый из них?)

525   5  
sql

5 ответов:

в двух словах:

NOT IN немного по-другому: он не соответствует, если есть только один NULL в списке.

  • на MySQL,NOT EXISTS - это немного менее эффективным!--16-->

  • на SQL Server,LEFT JOIN / IS NULL менее эффективен

  • на PostgreSQL,NOT IN менее эффективен

  • на Oracle, все три методы те же самые.

Если база данных хорошо оптимизирует запрос, два первых будут преобразованы в нечто близкое к третьему.

для простых ситуаций, подобных тем, о которых вы спрашиваете, не должно быть никакой разницы, так как все они будут выполняться как соединения. В более сложных запросах база данных может быть не в состоянии сделать соединение из not in и not exists queryes. В этом случае запросы будут намного медленнее. С другой стороны, соединение может также работать плохо, если есть нет индекса, который можно использовать, поэтому только потому, что вы используете соединение, не означает, что вы в безопасности. Вам нужно будет изучить план выполнения запроса, чтобы определить, могут ли быть какие-либо проблемы с производительностью.

предполагая, что вы избегаете нулей, они все способы написания анти-вступите использование стандартного 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

    Ничего не найдено.