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

Когда использовать SQL-запросы по сравнению со стандартным соединением?

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

Любая помощь будет оценена.

4b9b3361

Ответ 1

Подзапросы обычно хороши, если они не являются зависимыми подзапросами (также называемыми коррелированными подзапросами). Если вы используете только независимые подзапросы и используете соответствующие индексы, они должны запускаться быстро. Если у вас есть зависимый подзапрос, вы можете столкнуться с проблемами производительности, потому что зависимый подзапрос обычно должен выполняться один раз для каждой строки во внешнем запросе. Поэтому, если ваш внешний запрос имеет 1000 строк, подзапрос будет выполняться 1000 раз. С другой стороны, независимый подзапрос обычно нужно оценивать только один раз.

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

Если вы получите синтаксическую ошибку, потому что она относится к некоторым таблицам вне подзапроса, тогда ее a dependent subquery.

Общее правило, конечно, имеет несколько исключений. Например:

  • Многие оптимизаторы могут использовать зависимый подзапрос и найти способ эффективно его запускать как JOIN. Например, запрос NOT EXISTS может привести к плану запроса ANTI JOIN, поэтому он не обязательно будет медленнее, чем запись запроса с помощью JOIN.
  • MySQL имеет bug, где независимый подзапрос внутри выражения IN неправильно идентифицируется как зависимый подзапрос, и поэтому субоптимальный план запроса используемый. Это, по-видимому, исправлено в самых новых версиях MySQL.

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

Ответ 2

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

select nickname, (select top 1 votedate from votes where user_id=u.id order by 1 desc)
from users u

С другой стороны, EXISTS и NOT EXISTS запросы будут выигрывать через JOINs.

select ...
where NOT EXISTS (.....)

Обычно быстрее, чем

select ...
FROM A LEFT JOIN B
where B.ID is null

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

Ответ 3

К сожалению, ответ сильно зависит от используемого вами SQL-сервера. Теоретически, соединения лучше с точки зрения чисто реляционной теории. Они позволяют серверу делать правильные вещи под капотом и дают им больше контроля и, следовательно, в конце концов, могут быть быстрее. Если сервер хорошо реализован. На практике некоторые SQL-серверы работают лучше, если вы обманываете его для оптимизации запросов посредством подзапросов и т.п.