Цель SQL существует, а не существует - PullRequest
8 голосов
/ 17 декабря 2010

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

Я считаю, что они вводят в заблуждение (их, вероятно, сложнее точно визуализировать по сравнению с обычными объединениями и подзапросами), часто неправильно понимают (например, использование SELECT * будет вести себя так же, как SELECT 1 в подзапросе EXISTS/NOT EXISTS) и из моего ограниченного опыта, медленнее выполнить.

Может ли кто-нибудь описать и / или предоставить мне пример, где они лучше всего подходят или где нет другого выбора, кроме как использовать их? Обратите внимание, что поскольку их выполнение и производительность, вероятно, зависят от платформы, меня особенно интересует их использование в MySQL .

Ответы [ 3 ]

4 голосов
/ 20 декабря 2010

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

Эта статья (хотя SQL Server относится):

может представлять интерес для вас.

В двух словах, JOIN - это операция над множествами, а EXISTS - это предикат.

Другими словами, эти запросы:

SELECT  *
FROM    a
JOIN    b
ON      some_condition(a, b)

против

SELECT  *
FROM    a
WHERE   EXISTS
        (
        SELECT  NULL
        FROM    b
        WHERE   some_condition(a, b)
        )

не одинаковы: первый может вернуть более одной записи из a, в то время как последний не может.

Их аналоги, NOT EXISTS против LEFT JOIN / IS NULL, те же логически, но не с точки зрения производительности.

На самом деле, первый может быть более эффективным в SQL Server:

1 голос
/ 17 декабря 2010

Вы не можете [легко] использовать объединение в операторе UPDATE, поэтому WHERE EXISTS отлично работает там:

UPDATE mytable t
   SET columnX = 'SomeValue'
 WHERE EXISTS 
   (SELECT 1 
      FROM myothertable ot
     WHERE ot.columnA = t.columnY
       AND ot.columnB = 'XYX'
   );

Редактировать: это основано на Oracle больше, чем на MySQL, и даЕсть способы сделать это со встроенным представлением, но ИМХО это чище.

1 голос
/ 17 декабря 2010

, если основной запрос вернул намного меньше строк, чем таблица, в которой вы хотите их найти.пример:

SELECT st.State
FROM states st
WHERE st.State LIKE 'N%' AND EXISTS(SELECT 1 FROM addresses a WHERE a.State = st.State)

выполнение этого с объединением будет намного медленнее.или лучший пример, если вы хотите выполнить поиск, если элемент существует в 1 из нескольких таблиц.

...