Intereting Posts
mysql + update top n sqlConnection / Команда using statement + блок try / catch Огромные различия в производительности между sum (column_name), sum (1) и count (*) на большом наборе данных Существует в курсоре, где выполняется условие Postgres: определение самой длинной полосы (в днях) для каждого разработчика Oracle: используйте два индекса Внешний ключ, ссылающийся на несколько таблиц Доступ к базе данных C ++ без обязательной установки Из чего защищают вас параметры sql? Как отображать все месяцы в результатах сводных запросов, даже если данные за данный месяц Проблемы с пространственной репликацией данных Spatial Data Это нормально, если у вас есть алфавитно-цифровое поле в качестве PrimaryKey? Поиск дубликатов в таблице MYSQL, где данные находятся в нескольких таблицах (требуется несколько условий) Oracle sql: использование переменной привязки для дат Ссылка на таблицы внешнего запроса в подзапросе

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

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

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

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

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

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

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

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

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

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

 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 

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

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