isnull (email, '') = '' НЕ интерпретируется как само по себе (электронная почта пуста или электронная почта = '')? - PullRequest
0 голосов
/ 17 ноября 2009

как факт производительности, какой из них лучше? Есть ли разница между 3-мя версиями sql-сервера (2000/2005/2008)?

Ответы [ 2 ]

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

Вы определенно хотите избежать использования любых пользовательских или встроенных функций, обертывающих столбец в фильтре - это сильно ограничивает то, что оптимизатор может сделать для вас с точки зрения использования индекса и поиска. Вы должны привыкнуть использовать операторы равенства и / или подходы, когда это возможно, как здесь. Следующее было бы намного предпочтительнее подхода isnull () или coalesce ():

where   (
            (t.email is null)
            or
            (t.email = '')
        )

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

Простой пример продемонстрирует радикальные различия, которые вы можете увидеть в производительности:

use tempdb;
go
if object_id('tempdb..#testTable') > 0
    drop table #testTable;
go
-- Build the dataset
select  top 10000000
        cast(cast(a.name as varchar(100)) + '@' + cast(row_number() over (order by a.object_id) as varchar(15)) + '.com' as varchar(150)) as email, 
        row_number() over (order by a.object_id) as id
into    #testTable
from    sys.columns a
cross join sys.columns b
cross join sys.columns c
go
-- Create some nulls
update  #testTable
set     email = null
where   id % 1000 = 0
go
-- Index
create unique clustered index ixc__dbo_testTable__temp__nc1 on #testTable (email,id) on [default];
go
set statistics io on;
set statistics time on;
go
-- Try with isnull - ~cost of about 44.7 on my machine, ~2900ms to execute, and about 49,200 logical reads
select  *
from    #testTable t
where   isnull(t.email,'') = '';
go
-- Try with 'or' - ~cost of about .049 on my machine, ~643ms to execute, about 31 logical reads
select  *
from    #testTable t
where   (
            (t.email is null)
            or
            (t.email = '')
        );
go
-- Try with union approach - ~cost of about .054 on my machine, ~751ms to execute, ~30 logical reads
select  *
from    #testTable t
where   t.email is null
union all
select  *
from    #testTable t
where   t.email = '';
go
if object_id('tempdb..#testTable') > 0
    drop table #testTable;
go
0 голосов
/ 17 ноября 2009

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

Я считаю, что предпочтительный стиль -

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