Я хочу знать, есть ли у меня запрос на соединение примерно так -
Select E.Id,E.Name from Employee E join Dept D on E.DeptId=D.Id
и подзапрос вроде этого -
Select E.Id,E.Name from Employee Where DeptId in (Select Id from Dept)
Когда я рассматриваю производительность, какой из двух запросов будет быстрее и почему ?
Также есть ли время, когда я должен предпочесть одно другому?
Извините, если это слишком тривиально и спрашивали раньше, но я смущен этим. Кроме того, было бы здорово, если бы вы, ребята, могли предложить мне инструменты, которые я должен использовать для измерения производительности двух запросов. Большое спасибо!
Ответы:
Я ОЖИДАЛ, что первый запрос будет быстрее, в основном потому, что у вас есть эквивалент и явное СОЕДИНЕНИЕ. По моему опыту
IN
, это очень медленный оператор, поскольку SQL обычно оценивает его как сериюWHERE
предложений, разделенных «ИЛИ» (WHERE x=Y OR x=Z OR...
).Однако, как и в случае с ALL THINGS SQL, ваш опыт может отличаться. Скорость будет во многом зависеть от индексов (есть ли у вас индексы для обоих столбцов идентификатора? Это очень поможет ...), среди прочего.
Единственный НАСТОЯЩИЙ способ сказать со 100% уверенностью, что быстрее, - это включить отслеживание производительности (особенно полезна статистика ввода-вывода) и запустить их оба. Обязательно очищайте кеш между запусками!
источник
Что ж, я считаю, что это вопрос "старый, но золотой". Ответ: «Как много!». Спектакли - настолько деликатная тема, что было бы слишком глупо сказать: «Никогда не используйте подзапросы, всегда присоединяйтесь». По следующим ссылкам вы найдете некоторые основные передовые методы, которые, как я считаю, очень полезны:
У меня есть таблица с 50000 элементами, результат, который я искал, был 739 элементов.
Сначала мой запрос был таким:
на выполнение потребовалось 7,9 секунды.
Наконец, мой запрос таков:
и потребовалось 0,0256 с
Хороший SQL, хорошо.
источник
Начните смотреть на планы выполнения, чтобы увидеть различия в том, как сервер SQl их интерпретирует. Вы также можете использовать Profiler для фактического выполнения запросов несколько раз и получения различий.
Я не ожидал, что они будут настолько ужасно разными, где вы можете получить реальный, большой выигрыш в производительности при использовании объединений вместо подзапросов, когда вы используете коррелированные подзапросы.
EXISTS часто лучше, чем любой из этих двух, и когда вы говорите о левых соединениях, когда вы хотите, чтобы все записи не были в левой таблице соединений, тогда NOT EXISTS часто является гораздо лучшим выбором.
источник
Производительность зависит от объема данных, над которыми вы выполняете ...
Если данных меньше в районе 20к. JOIN работает лучше.
Если данные больше похожи на 100k +, то IN работает лучше.
Если вам не нужны данные из другой таблицы, используйте IN, но всегда лучше использовать EXISTS.
Все эти критерии я тестировал, и таблицы имеют правильные индексы.
источник
Спектакль должен быть таким же; Гораздо важнее, чтобы к вашим таблицам применялись правильные индексы и кластеризация (есть несколько хороших ресурсов по этой теме).
(Отредактировано, чтобы отразить обновленный вопрос)
источник
Эти два запроса могут не быть семантически эквивалентными. Если сотрудник работает более чем в одном отделе (возможно, на предприятии, в котором я работаю; по общему признанию, это будет означать, что ваша таблица не полностью нормализована), то первый запрос вернет повторяющиеся строки, а второй - нет. Чтобы сделать запросы эквивалентными в этом случае,
DISTINCT
необходимо добавить ключевое слово вSELECT
предложение, что может повлиять на производительность.Обратите внимание, что существует практическое правило проектирования, согласно которому таблица должна моделировать сущность / класс или отношения между сущностями / классами, но не то и другое вместе. Поэтому я предлагаю вам создать третью таблицу, скажем
OrgChart
, для моделирования отношений между сотрудниками и отделами.источник
Я знаю, что это старый пост, но я думаю, что это очень важная тема, особенно в наши дни, когда у нас более 10 миллионов записей и мы говорим о терабайтах данных.
Я также остановлюсь на следующих наблюдениях. У меня около 45 миллионов записей в моей таблице ([data]) и около 300 записей в моей таблице [cats]. У меня есть обширная индексация для всех запросов, о которых я собираюсь рассказать.
Рассмотрим пример 1:
по сравнению с примером 2:
Выполнение примера 1 заняло около 23 минут. Пример 2 занял около 5 минут.
Итак, я бы сделал вывод, что подзапрос в этом случае выполняется намного быстрее. Конечно, имейте в виду, что я использую твердотельные накопители M.2 с возможностью ввода-вывода @ 1 ГБ / сек (это байты, а не биты), поэтому мои индексы тоже очень быстрые. Так что это может повлиять и на скорость в ваших обстоятельствах
Если это разовая очистка данных, вероятно, лучше всего просто оставить ее запущенной и закончить. Я использую TOP (10000) и смотрю, сколько времени это займет, и умножаю на количество записей, прежде чем попаду в большой запрос.
Если вы оптимизируете производственные базы данных, я настоятельно рекомендую выполнить предварительную обработку данных, то есть использовать триггеры или брокера заданий для асинхронного обновления записей, чтобы доступ в реальном времени извлекал статические данные.
источник
Вы можете использовать план объяснения, чтобы получить объективный ответ.
Для вашей проблемы фильтр Exists , вероятно, будет работать быстрее всего.
источник