2009-11-12 2 views
5

У меня есть запрос, как показано ниже:Вызов функции в пункте, где

SELECT * FROM Members (NOLOCK) 
WHERE Phone= dbo.FormatPhone(@Phone) 

Теперь здесь я понимаю, что форматирование должно быть применено на переменном на колонке. Но следует ли применить его к переменной для назначения какой-либо другой локальной переменной, а затем использовать ее (как показано ниже).

Set @SomeVar = dbo.FormatPhone(@Phone) 

SELECT * 
    FROM Members (NOLOCK) WHERE Phone= @SomeVar 

Какой способ лучше или оба хороши?

EDIT: И как первый запрос отличается от

SELECT * FROM Members (NOLOCK) 
WHERE dbo.FormatPhone(Phone) = @Phone 

ответ

7

Как обычно в SQL, запрос в значительной степени является релевантным, не зная, к какой фактической схеме используется.

У вас есть указатель на Member.Phone? Если нет, то не имеет значения, как вы пишете запрос, все они сканируют всю таблицу и выполняют одно и то же (т. Е. Плохо работают). Если есть индекс то, как вы пишете запрос делает все различия:

SELECT * FROM Members WHERE Phone= @Phone; 
SELECT * FROM Members WHERE Phone= dbo.FormatPhone(@Phone); 
SELECT * FROM Members WHERE dbo.FormatPhone(Phone)[email protected]; 

Первый запрос гарантируется оптимальным, будет искать телефон по индексу.
Второй запрос зависит от характеристик dbo.FormatPhone. Он может или не может использовать оптимальный поиск.
Последний запрос гарантированно будет ошибкой. Сканирует таблицу.

Кроме того, я удалил подсказку NOLOCK, она кажется темой дня ... См. syntax for nolock in sql. NOLOCK всегда неправильный ответ. Используйте изоляцию моментальных снимков.

+0

Я прошел через сообщение, и в нем говорится о том, что я не использую NOLOCK с инструкциями Update/Insert. почему вы здесь проблема? –

+0

Вы имеете в виду использование с (nolock) вместо NOLOCK? –

+0

Вы * намерение * читать неактивные данные? Или вы добавили NOLOCK в качестве обходного пути для решения проблем с совместимостью? –

4

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

+0

Кроме того, первый вариант, скорее всего, не сможет использовать индекс. – Kuberchaun

+0

Оценка функции для каждой строки будет там, если мы применим функцию в столбце или переменной таблицы? Или оба пути одинаковы? –

+0

Нет, если вы выполняете вычисление спереди, вы по существу передаете запрос константе. –

5

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

0
SELECT * FROM Members (NOLOCK) 
WHERE Phone= dbo.FormatPhone(@Phone) 

в приведенном выше запросе, function dbo.FormatPhone будет выполняться для каждой строки в таблице Members.

когда второй запрос

Set @SomeVar = dbo.FormatPhone(@Phone) 

SELECT * 
FROM Members (NOLOCK) WHERE Phone= @SomeVar 

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

+0

Спасибо vrunda. У меня разные отзывы и мнения здесь, хотя я не что функция будет выполняться для каждой строки в первом запросе. У вас есть ссылки, подтверждающие это? –