Разница между EXISTS и IN в SQL?

В чем разница между предложением EXISTS и IN в SQL?

Когда мы должны использовать EXISTS, и когда следует использовать IN?

Ответ 1

Ключевое слово exists может использоваться таким образом, но на самом деле оно предназначено как способ избежать подсчета:

--this statement needs to check the entire table
select count(*) from [table] where ...

--this statement is true as soon as one match is found
exists ( select * from [table] where ... )

Это наиболее полезно, если у вас есть условные выражения if, поскольку exists может быть намного быстрее, чем count.

in лучше всего использовать, когда у вас есть статический список:

 select * from [table]
 where [field] in (1, 2, 3)

Когда у вас есть таблица в выражении in, имеет смысл использовать join, но в основном это не имеет значения. Оптимизатор запросов должен возвращать тот же план в любом случае. В некоторых реализациях (в основном старше, например Microsoft SQL Server 2000) запросы in всегда будут получать вложенное соединение, а join запросы будет использовать вложенный, merge или хэш, если это необходимо. Более современные реализации умнее и могут корректировать план, даже если используется in.

Ответ 2

EXISTS сообщит вам, возвращает ли запрос какие-либо результаты. например:.

SELECT * 
FROM Orders o 
WHERE EXISTS (
    SELECT * 
    FROM Products p 
    WHERE p.ProductNumber = o.ProductNumber)

IN используется для сравнения одного значения с несколькими и может использовать литеральные значения, например:

SELECT * 
FROM Orders 
WHERE ProductNumber IN (1, 10, 100)

Вы также можете использовать результаты запроса с предложением IN, например:

SELECT * 
FROM Orders 
WHERE ProductNumber IN (
    SELECT ProductNumber 
    FROM Products 
    WHERE ProductInventoryQuantity > 0)

Ответ 3

На основе оптимизатора правил:

  • EXISTS намного быстрее, чем IN, когда результаты подзапроса очень велики.
  • IN быстрее, чем EXISTS, когда результаты суб-запроса очень малы.

На основе оптимизатора затрат:

  • Нет никакой разницы.

Ответ 4

Я предполагаю, что вы знаете, что они делают, и поэтому используются по-разному, поэтому я буду понимать ваш вопрос так: Когда было бы хорошей идеей переписать SQL для использования IN вместо EXISTS или наоборот наоборот.

Это справедливое предположение?


Изменить. Причина, по которой я спрашиваю, заключается в том, что во многих случаях вы можете переписать SQL на основе IN для использования EXISTS вместо этого, и наоборот, а для некоторых движков базы данных оптимизатор запросов будет обрабатывать два по-разному.

Например:

SELECT *
FROM Customers
WHERE EXISTS (
    SELECT *
    FROM Orders
    WHERE Orders.CustomerID = Customers.ID
)

можно переписать на:

SELECT *
FROM Customers
WHERE ID IN (
    SELECT CustomerID
    FROM Orders
)

или с соединением:

SELECT Customers.*
FROM Customers
    INNER JOIN Orders ON Customers.ID = Orders.CustomerID

Итак, мой вопрос по-прежнему стоит, является ли исходный плакат вопросом о том, что делает IN и EXISTS, и, следовательно, как его использовать, или он попросит переписать SQL, используя IN для использования EXISTS вместо этого, или наоборот, будет хорошая идея?

Ответ 5

  • EXISTS намного быстрее, чем IN, когда результаты подзапроса очень велики.
    IN быстрее, чем EXISTS, когда результаты подзапроса очень малы.

    CREATE TABLE t1 (id INT, title VARCHAR(20), someIntCol INT)
    GO
    CREATE TABLE t2 (id INT, t1Id INT, someData VARCHAR(20))
    GO
    
    INSERT INTO t1
    SELECT 1, 'title 1', 5 UNION ALL
    SELECT 2, 'title 2', 5 UNION ALL
    SELECT 3, 'title 3', 5 UNION ALL
    SELECT 4, 'title 4', 5 UNION ALL
    SELECT null, 'title 5', 5 UNION ALL
    SELECT null, 'title 6', 5
    
    INSERT INTO t2
    SELECT 1, 1, 'data 1' UNION ALL
    SELECT 2, 1, 'data 2' UNION ALL
    SELECT 3, 2, 'data 3' UNION ALL
    SELECT 4, 3, 'data 4' UNION ALL
    SELECT 5, 3, 'data 5' UNION ALL
    SELECT 6, 3, 'data 6' UNION ALL
    SELECT 7, 4, 'data 7' UNION ALL
    SELECT 8, null, 'data 8' UNION ALL
    SELECT 9, 6, 'data 9' UNION ALL
    SELECT 10, 6, 'data 10' UNION ALL
    SELECT 11, 8, 'data 11'
    
  • Запрос 1

    SELECT
    FROM    t1 
    WHERE   not  EXISTS (SELECT * FROM t2 WHERE t1.id = t2.t1id)
    

    Запрос 2

    SELECT t1.* 
    FROM   t1 
    WHERE  t1.id not in (SELECT  t2.t1id FROM t2 )
    

    Если в t1 ваш id имеет нулевое значение, то Query 1 найдет их, но Query 2 не сможет найти нулевые параметры.

    Я имею в виду, что IN не может сравнивать ничего с NULL, поэтому он не имеет результата для null, но EXISTS может сравнивать все с нулевым.

Ответ 6

Если вы используете оператор IN, механизм SQL будет проверять все записи, извлеченные из внутреннего запроса. С другой стороны, если мы используем EXISTS, механизм SQL остановит процесс сканирования, как только найдет совпадение.

Ответ 7

Ключевое слово Exists оценивает значение true или false, но ключевое слово IN сравнивает все значения в соответствующем столбце подзапроса. Другой Select 1 может использоваться с командой Exists. Пример:

SELECT * FROM Temp1 where exists(select 1 from Temp2 where conditions...)

Но IN менее эффективен, поэтому Exists быстрее.

Ответ 8

IN поддерживает только отношения равенства (или неравенство, когда ему предшествует НЕ).
Это синоним = любой/= some, например

select    * 
from      t1 
where     x in (select x from t2)
;

EXISTS поддерживает варианты типов отношений, которые не могут быть выражены с помощью IN, например. -

select    * 
from      t1 
where     exists (select    null 
                  from      t2 
                  where     t2.x=t1.x 
                        and t2.y>t1.y 
                        and t2.z like '℅' || t1.z || '℅'
                  )
;

И на другую ноту -

Предполагается, что производительность и технические различия между EXISTS и IN могут возникать из-за конкретных реализаций/ограничений/ошибок поставщика, но во многих случаях это ничего, кроме мифов, созданных из-за отсутствия понимания внутренних систем баз данных.

Определение таблиц, точность статистики, конфигурация базы данных и версия оптимизатора оказывают влияние на план выполнения и, следовательно, на показатели производительности.

Ответ 9

Я думаю,

  • EXISTS - это когда вам нужно сопоставить результаты запроса с другим подзапросом. Результаты запроса # 1 должны быть получены, когда результаты SubQuery совпадают. Вид Присоединиться.. Например. выберите таблицу клиентов №1, которые также разместили таблицу заявок # 2.

  • IN следует извлекать, если значение конкретного столбца содержит IN список (1,2,3,4,5) Например. Выберите клиентов, которые находятся в следующих zipcodes, то есть значения zip_code находятся в списке (....).

Когда использовать один над другим... когда вы чувствуете, что он читает правильно (лучше взаимодействует).

Ответ 10

Здесь разница:

select * 
from abcTable
where exists (select null)

Выше запроса вернет все записи, а ниже будет возвращено пустое.

select *
from abcTable
where abcTable_ID in (select null)

Попробуйте и посмотрите результат.

Ответ 11

Как известно, когда подзапрос возвращает значение NULL, весь оператор становится NULL. В этом случае мы используем ключевое слово EXITS. Если мы хотим сравнить определенные значения в подзапросах, то мы используем ключевое слово IN.

Ответ 12

Какой из них быстрее, зависит от количества запросов, полученных внутренним запросом:

  • Когда ваш внутренний запрос выбирает тысячи строк, тогда EXIST будет лучшим выбором
  • Когда ваш внутренний запрос извлекает несколько строк, тогда IN будет быстрее

EXIST оценивает значение true или false, но IN сравнивает множественное значение. Когда вы не знаете, что запись существует или нет, вы должны выбрать EXIST

Ответ 13

Причина в том, что оператор EXISTS работает на основе принципа "по крайней мере, найденного". Он возвращает true и останавливает таблицу сканирования, если найдена хотя бы одна соответствующая строка.

С другой стороны, когда оператор IN объединен с подзапросом, MySQL сначала обрабатывает подзапрос, а затем использует результат подзапроса для обработки всего запроса.

Общее правило состоит в том, что если в подзапрос содержит большой объем данных, оператор EXISTS обеспечивает лучшую производительность.

Однако запрос, который использует оператор IN, будет работать быстрее, если результирующий набор, возвращенный из подзапроса, очень мал.

Ответ 14

Мое понимание - это то же самое, если мы не имеем дело с значениями NULL.

По той же причине, почему запрос не возвращает значение для = NULL vs имеет значение NULL. http://sqlinthewild.co.za/index.php/2010/02/18/not-exists-vs-not-in/

Как для логического аргумента сравнения или сравнения, для генерации логического значения оба значения нужно сравнивать, и именно так работает любое условие. Поэтому я не понимаю, как IN и EXISTS ведут себя по-разному ,

Ответ 15

Если подзапрос возвращает более одного значения, вам может потребоваться выполнить внешний запрос - если значения в столбце, указанном в условии, соответствуют любому значению в результирующем наборе подзапроса. Для выполнения этой задачи вам нужно использовать ключевое слово in.

Вы можете использовать подзапрос, чтобы проверить, существует ли набор записей. Для этого вам нужно использовать предложение exists с подзапросом. Ключевое слово exists всегда возвращает значение true или false.

Ответ 16

Я считаю, что у этого есть прямой ответ. Почему бы вам не проверить его у людей, которые разработали эту функцию в своих системах?

Если вы разработчик MS SQL, вот ответ от Microsoft.

IN:

Определяет, соответствует ли указанное значение любому значению в подзапросе или списке.

EXISTS:

Задает подзапрос для проверки существования строк.

Ответ 17

Я обнаружил, что использование ключевого слова EXISTS часто очень медленное (это очень верно в Microsoft Access). Вместо этого я использую оператор объединения таким образом: should-i-use-the-keyword-exists-in-sql

Ответ 19

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

Ответ 20

Если вы используете оператор IN, механизм SQL будет сканировать все записи, извлеченные из внутреннего запроса. С другой стороны, если мы используем EXISTS, механизм SQL остановит процесс сканирования, как только найдет совпадение.