作为一个表现更好的事实?实际的三个版本的sql-server(2000/2005 / 2008)之间是否存在差异?
答案 0 :(得分:3)
您肯定希望避免使用任何custom or built-in functions wrapping a column in a filter - 它严重限制了优化程序在索引使用和可搜索性方面可以为您做的事情。你应该养成在可能的情况下使用相等运算符和/或联合方法的习惯,就像这里的情况一样。以下将比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
答案 1 :(得分:0)
如果你要看到性能差异,他们会很快。
我相信首选的风格是
ISNULL(email, '') = ''