Подтвердить что ты не робот

Transact-SQL - дополнительный запрос или левое соединение?

У меня есть две таблицы, содержащие "Задачи" и "Заметки", и вы хотите получить список задач с количеством связанных заметок для каждого из них. Эти два запроса выполняются:

select t.TaskId,
       (select count(n.TaskNoteId) from TaskNote n where n.TaskId = t.TaskId) 'Notes'
from   Task t

-- or
select t.TaskId,
       count(n.TaskNoteId) 'Notes'
from   Task t
left join
       TaskNote n
on     t.TaskId = n.TaskId
group by t.TaskId

Есть ли разница между ними, и я должен использовать один над другим, или это всего лишь два способа выполнения одной и той же работы? Спасибо.

4b9b3361

Ответ 1

На небольших наборах данных они стираются, когда дело доходит до производительности. При индексировании LOJ немного лучше.

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

Ответ 2

В большинстве случаев оптимизатор будет относиться к ним одинаково.

Я предпочитаю второй вариант, потому что у него меньше гнездования, что упрощает чтение и упрощает его поддержку. Я начал использовать общие табличные выражения SQL Server для уменьшения вложенности по той же причине.

Кроме того, второй синтаксис более гибкий, если есть дополнительные агрегаты, которые могут быть добавлены в будущем в дополнение к COUNT, например MIN (some_scalar), MAX(), AVG() и т.д.

Ответ 3

Подзапрос будет медленнее, поскольку он выполняется для каждой строки во внешнем запросе. Соединение будет быстрее, как это делается один раз. Я считаю, что оптимизатор запросов не будет переписывать этот план запроса, поскольку он не может распознать эквивалентность.

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

Ответ 4

Если вы используете SQL Server Management Studio, вы можете ввести обе версии в редактор запросов, а затем щелкнуть правой кнопкой мыши и выбрать "Показать примерный план выполнения". Это даст вам два процента затрат по сравнению с пакетом. Если ожидается, что они будут работать в одно и то же время, они будут отображаться как 50% - и в этом случае выберите, какой вы предпочитаете по другим причинам (легче читать, упрощать обслуживание, лучше вписываться в ваши стандарты кодирования и т.д.). В противном случае вы можете выбрать тот, у которого более низкая процентная стоимость относительно партии.

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

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

Ответ 5

На этот вопрос нет четкого ответа. Вы должны просмотреть SQL-план. В терминах реляционной алгебры они существенно эквивалентны.

Ответ 6

Я делаю все возможное, чтобы избежать подзапросов, где это возможно. Соединение, как правило, будет более эффективным.

Ответ 7

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

Если производительность является проблемой, поэкспериментируйте с переписыванием запроса с использованием другой формы. Иногда оптимизатор будет использовать индекс для одной формы, а не другой.