Оператор производительности SQL-запроса «<>» vs NOT EXISTS - PullRequest
1 голос
/ 12 ноября 2009

Я работаю над оптимизацией одного из заданий SQL.

Здесь у меня есть несколько мест, где мы использовали оператор <>. Тот же запрос можно заменить с помощью оператора NOT EXISTS. Мне просто интересно, какой лучший способ сделать это.

Пример запроса

If(@Email <> (select Email from Members WHERE MemberId = @MemberId)) 
--Do Something.

--Same thing can be written as 
If(NOT EXISTS (SELECT Email FROM Members WHERE MemberId = @MemberId AND Email = @EmailId))

Что лучше?

Я выполнил оба плана выполнения (не могу присоединиться, так как весь хостинг изображений заблокирован в офисе). Я вижу, что оператор <> имеет больше операций Assert и Stream Aggregate, чем NOT EXISTS. Не уверен, что они хорошие или плохие или не влияют.

Ответы [ 2 ]

3 голосов
/ 12 ноября 2009

NOT EXISTS обычно лучше (хотя в вашем случае, если таблица небольшая и / или проиндексирована должным образом, это может быть не так).

Почти всегда вы должны использовать EXISTS / NOT EXISTS для запросов, в которых вы пытаетесь выяснить, существует ли определенная запись (или не существует)!

Причина заключается в том, что запросы EXISTS (и NOT EXISTS) будут остановлены, как только условие будет выполнено (или в случае, если NOT EXISTS окажется ложным), в отличие от использования подзапросов, которые продолжат сканирование записей через весь стол.

1 голос
/ 12 ноября 2009

Разница между вашими двумя утверждениями заключается в вопросе "сколько сделано в чистом SQL, и сколько сделано движком, выполняющим процедуры / сценарии и т. Д. (Я хотел бы сказать, что делает база данных и что находится за пределами базы данных, но в хранимом процессе обе части обрабатываются базой данных.)

В вашем примере первый оператор использует SQL для извлечения электронной почты одного члена. В доступе к таблице используется первичный ключ и связанный с ним уникальный индекс, поэтому он должен быть очень быстрым даже для большой таблицы. EMail передается за пределы SQL, а затем выполняется сравнение в сценарии.

Во втором описании происходит почти то же самое. MemberID снова используется для доступа к уникальной записи, затем сравнивается электронное письмо и логический результат передается обратно за пределы SQL.

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

Будут разные соображения (например, как отметил MikyD), когда нужно перенести более одного значения за пределы SQL и выполнить более сложное сравнение (например, выбрать большое количество писем с использованием SQL, а затем выполнить сравнение в скрипте с чем-то вроде Email IN (Select ..)). Тогда обычно предпочтительнее выполнять как можно больше работы в SQL, передавать наименьшее количество данных между SQL и не-SQL и позволить базе данных определить наиболее эффективный способ получения данных.

...