Подзапрос против внешнего соединения

Рассмотрим следующие 2 вопроса:

select tblA.a,tblA.b,tblA.c,tblA.d
from tblA
where tblA.a not in (select tblB.a from tblB)

select tblA.a,tblA.b,tblA.c,tblA.d
from tblA left outer join tblB
on tblA.a = tblB.a where tblB.a is null

Что будет работать лучше? Я предполагаю, что в целом соединение будет лучше, за исключением случаев, когда подзапрос возвращает очень маленький набор результатов.

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
8
0
6 068
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

По моим наблюдениям, сервер MSSQL выдает один и тот же план запроса для этих запросов.

Я создал простой запрос, аналогичный тем, что был в вопросе о MSSQL2005, и планы объяснения были другими. Первый запрос оказывается быстрее. Я не эксперт по SQL, но в предполагаемом плане объяснения было 37% для запроса 1 и 63% для запроса 2. Похоже, что самая большая стоимость для запроса 2 - это соединение. У обоих запросов было два просмотра таблицы.

Ответ принят как подходящий

РСУБД «переписывают» запросы, чтобы оптимизировать их, поэтому это зависит от используемой вами системы, и я предполагаю, что они в конечном итоге дают такую ​​же производительность в большинстве «хороших» баз данных.

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

Я второй ответ Тома, что вы должны выбрать тот, который легче понять и поддерживать.

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

Как правило, я обычно использую подвыборки, когда мне не нужно включать какие-либо столбцы из tblB в мое предложение select. Я бы определенно выбрал подвыборку, когда хочу использовать предикат 'in' (и обычно для 'not in', которое вы включили в вопрос) по той простой причине, что это легче понять, когда вы или кто-то еще вернулся и изменил их.

Первый запрос будет быстрее в SQL Server, что, на мой взгляд, немного интуитивно понятно - подзапросы казаться, как будто они должны быть медленнее. В некоторых случаях (по мере увеличения объемов данных) exists может быть быстрее, чем in.

некоррелированные подзапросы - это нормально. вы должны выбрать то, что описывает данные, которые вам нужны. как было отмечено, это, вероятно, будет переписано в тот же план, но не гарантируется! более того, если таблицы A и B не являются 1: 1, вы получите повторяющиеся кортежи из запроса соединения (поскольку предложение IN выполняет неявную сортировку DISTINCT), поэтому всегда лучше кодировать то, что вы хотите, и на самом деле думать о результате.

Следует отметить, что эти запросы будут давать разные результаты, если TblB.a не уникален.

Ну, это зависит от наборов данных. По моему опыту, если у вас небольшой набор данных, выберите NOT IN, если он большой, выберите LEFT JOIN. Предложение NOT IN кажется очень медленным для больших наборов данных.

Еще я мог бы добавить, что планы объяснения могут вводить в заблуждение. Я видел несколько запросов, в которых объяснение было очень высоким, а запрос выполнялся ниже 1 с. С другой стороны, я видел запросы с отличным планом объяснения, которые могли выполняться часами.

В общем, проверьте свои данные и убедитесь в этом сами.

Другие вопросы по теме