Когда использовать подзапросы SQL по сравнению со стандартным соединением? - PullRequest
32 голосов
/ 26 января 2011

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

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

Ответы [ 3 ]

48 голосов
/ 26 января 2011

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

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

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

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

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

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

6 голосов
/ 26 января 2011

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

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

С другой стороны, запросы EXISTS и NOT EXISTS выиграют у JOIN.

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

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

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

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

4 голосов
/ 26 января 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...