У мене є випадок, коли використання ПРИЄДНАННЯ або ІН дасть мені правильні результати ... Що зазвичай має кращу ефективність і чому? Скільки це залежить від того, на якому сервері баз даних ви працюєте? (FYI я використовую MSSQL)
У мене є випадок, коли використання ПРИЄДНАННЯ або ІН дасть мені правильні результати ... Що зазвичай має кращу ефективність і чому? Скільки це залежить від того, на якому сервері баз даних ви працюєте? (FYI я використовую MSSQL)
Відповіді:
Взагалі кажучи, IN
і JOIN
різні запити , які можуть призводити до різних результатів.
SELECT a.*
FROM a
JOIN b
ON a.col = b.col
не те саме, що
SELECT a.*
FROM a
WHERE col IN
(
SELECT col
FROM b
)
, якщо не b.col
є унікальним.
Однак це синонім першого запиту:
SELECT a.*
FROM a
JOIN (
SELECT DISTINCT col
FROM b
)
ON b.col = a.col
Якщо стовпець приєднання є UNIQUE
і позначений як такий, обидва ці запити дають однаковий план у SQL Server
.
Якщо ні, то IN
швидше, ніж JOIN
на DISTINCT
.
Дивіться цю статтю в моєму блозі, щоб отримати детальну інформацію про продуктивність:
IN
означає DISTINCT
. SQL Server
досить розумний, щоб його помітити, і створить однакові плани для обох запитів. Не впевнений, однак, як RDBMS
поводяться інші.
Смішно, що ви це згадали, я зробив допис у блозі на цю тему.
Див. Oracle vs MySQL vs SQL Server: Агрегація проти приєднання
Коротка відповідь: вам доведеться протестувати її, і окремі бази даних сильно відрізняються.
Це досить важко сказати - для того, щоб дійсно з’ясувати, який з них працює краще, вам потрібно було б насправді проаналізувати терміни виконання.
Як загальне правило, я думаю, якщо у вас є індекси на стовпцях із зовнішнім ключем, і якщо ви використовуєте лише (або в основному) умови ВНУТРІШНЬОГО ПРИЄДНАННЯ, то СПОЛУЧЕННЯ буде трохи швидше.
Але як тільки ви почнете використовувати зовнішній приєднання або якщо вам не вистачає індексів іноземних ключів, IN може стати швидшим.
Марк
Цікавий запис про логічні відмінності: SQL Server: JOIN vs IN vs EXISTS - логічна різниця
Я майже впевнений, що якщо припустити, що відносини та індекси підтримуються, Join приведе до кращого результату (більше зусиль спрямовано на роботу з цією операцією, ніж з іншими). Якщо ви думаєте про це концептуально, то його різниця між 2 запитами та 1 запитом.
Вам потрібно підключити його до аналізатора запитів і спробувати його і побачити різницю. Також подивіться План виконання запитів і спробуйте мінімізувати кроки.
Ця нитка досить стара, але все ще часто згадується. На мій особистий смак це трохи неповно, тому що є ще один спосіб запитати базу даних за ключовим словом EXISTS, яке я вважаю швидшим швидше.
Тож якщо вас цікавлять лише значення з таблиці a, ви можете використовувати цей запит:
SELECT a.*
FROM a
WHERE EXISTS (
SELECT *
FROM b
WHERE b.col = a.col
)
Різниця може бути величезною, якщо col не індексується, тому що db не повинен знаходити всі записи в b, які мають однакове значення в col, він повинен знайти лише перший. Якщо немає індексу на b.col і багато записів при скануванні таблиці таблиць може бути наслідком. З IN або JOIN це буде сканування повної таблиці, для EXISTS це буде лише часткове сканування таблиці (поки не буде знайдена перша відповідна запис).
Якщо в b є багато записів, які мають однакове значення col, ви також витратите багато пам’яті для того, щоб прочитати всі ці записи у тимчасовий простір лише для того, щоб знайти свій стан. З наявністю цього, як правило, можна уникнути.
Я часто знаходив EXISTS швидше, ніж IN, навіть якщо є індекс. Це залежить від системи бази даних (оптимізатора), даних і не в останню чергу від типу індексу, який використовується.
Впровадження кожної бази даних, але ви, напевно, можете здогадатися, що всі вони вирішують загальні проблеми більш-менш однаково. Якщо ви використовуєте MSSQL, перегляньте сформований план виконання. Це можна зробити, увімкнувши профайлер і плани виконання. Це дасть вам текстову версію під час виконання команди.
Я не впевнений, яку версію MSSQL ви використовуєте, але ви можете отримати графічну версію в SQL Server 2000 в аналізаторі запитів. Я впевнений, що ця функція ховається десь у SQL Server Studio Manager у більш пізніх версіях.
Погляньте на план виконання. Наскільки це можливо, уникайте сканувань таблиць, якщо, звичайно, ваша таблиця невелика, в цьому випадку сканування таблиці швидше, ніж використання індексу. Читайте про різні операції з'єднання, які виробляє кожен різний сценарій.
Оптимізатор повинен бути досить розумним, щоб дати вам однаковий результат у будь-якому випадку для звичайних запитів. Перевірте план виконання, і вони повинні дати вам те саме. Якщо вони цього не роблять, я, як правило, вважаю ПРИЄДНАЙТЕ швидше. Однак усі системи різні, тому вам слід переконатися в профілі коду в системі.