Join, Exists чи In? (SQL)

4 хв. читання

У минулі вихідні я натрапив на чудове візуальне пояснення JOIN-ів на Hacker News.

Це нагадало мені викладання SQL для партнерів PwC FTS кілька років тому. Мало хто з них мав раніше досвід програмування, ще менше - досвід роботи з SQL, тож було цікаво дізнатись, наскільки добре інструктори з США можуть викласти тему.

Більшість з них інтуїтивно схопили, як працює оператор IN, але спочатку мали проблеми з оператором EXISTS та JOIN-ами. Поясненням, що завжди допомагало проілюструвати концепцію, було показати, що часто можна написати той самий запит за допомогою IN, EXISTS і JOIN.

Для прикладу візьмемо наступні дві таблиці, які назвемо tableA and tableB. (В tableA - id працівника і його ім'я, в tableB - id працівника і його посада)

id  name    id  title
--  ----    --  ----
1   Kenny   1   Analyst
1   Rob     2   Sales
4   Molly   3   Manager
1   Greg
2   John

Якщо ми хочемо вибрати всіх аналітиків(Analyst), ми можемо використати наступний запит:

 SELECT  *
 FROM    tableA
 WHERE   tableA.id IN (SELECT tableB.id FROM tableB WHERE title = 'Analyst');

    -- запит повертає три записи - Kenny, Rob, і Greg

Для тих, хто не дуже знайомий з SQL, це має бути відносно легко. Ми написали підзапит що повертатиме id аналітика(Analyst) з таблиці tableB. Використовуючи IN, ми можемо вибрати всі записи з таблиці tableA що мають цей id, тобто всіх працівників що є аналітиками.

Запити з оператором IN є інтуїтивно зрозумілими, але вони часто менш ефективні, ніж такі ж запити, але написані з використанням операторів JOIN або EXISTS.

Для отримання тих самих результатів, що й вище, ми могли б зробити наступне:

   -- запит з використанням оператора EXISTS
SELECT  *
FROM    tableA
WHERE   EXISTS (SELECT 1 FROM tableB WHERE title = 'Analyst' AND tableA.id = tableB.id);
   -- з використанням оператора JOIN (за замовчанням якщо написано JOIN, то використовується INNER JOIN)
SELECT  *
FROM    tableA
JOIN    tableB
    ON  tableA.id = tableB.id
WHERE   tableB.title = 'Analyst';

В більшості випадків, EXISTS або JOIN будуть набагато ефективнішими (і швидшими) ніж оператор IN. Чому?

При використанні оператора IN в поєднанні з підзапитом, база даних має спочатку обробити підзапит, потім обробити запит в цілому, на основі зв'язку визначеного для IN.

При використанні операторів EXISTS або JOIN, база даних повертатиме true/false під час перевірки зазначеного зв'язку. Якщо таблиця в підзапиті не надто мала, EXISTS чи JOIN буде працювати набагато краще, ніж IN.

Крім того, написання запиту через JOIN дає нам додаткову гнучкість, бо ми можемо легко вибрати всіх спіробітників, якщо захочемо, або навіть знайти співробітників які не мають посади(записи-"сироти").

  -- вивести співробітників(з ім'ям і посадою)
SELECT  *
FROM    tableA
JOIN    tableB
    ON  tableA.id = tableB.id;
-- 1 Kenny  1 Analyst
-- 1 Rob    1 Analyst
-- 1 Greg   1 Analyst
-- 2 John   2 Sales
-- Який працівник не має посади?
SELECT  *
FROM    tableA
LEFT JOIN   tableB
    ON  tableA.id = tableB.id
WHERE   tableB.id IS NULL;
  -- 4 Molly  NULL NULL

В першому запиті вище, Molly випадає, бо вона не має посади. Якби ми хотіли щоб цей запис з'явився в списку результатів, ми могли б просто замінити JOIN на LEFT JOIN і отримали б Molly разом з даними типу NULL з таблиці tableB.

Якщо у вас по коду розсипано багато операторів IN, варто порівняти продуктивність цих запитів до тих самих запитів але з використанням EXISTS або JOIN - скоріш за все ви побачите збільшення продуктивності.

Сподіваюсь, вдалось показати деякі з тонких відмінностей між операторами IN, EXISTS, та JOIN.

Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 6.2K
Приєднався: 7 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація