IsNull (e-mail, '') = '' non è interpretato da esso stesso come (e-mail è nullo o e-mail = '')?
-
20-09-2019 - |
Domanda
come un fatto di prestazioni, che uno è meglio? C'è una differenza tra l'attuale 3 tre versioni di SQL server (2000/2005/2008)?
Soluzione
È sicuramente vuole evitare l'uso di qualsiasi personalizzata o funzioni incorporate nello spostamento di un colonna in un filtro - è ciò che limita fortemente l'ottimizzatore può fare per voi in termini di utilizzo dell'indice e seekability. Si dovrebbe prendere l'abitudine di usare operatori di uguaglianza e / o approcci sindacali quando possibile, come è il caso qui. Il seguente sarebbe di gran lunga preferito nel corso di un IsNull () o fondersi () approccio:
where (
(t.email is null)
or
(t.email = '')
)
o la politica dell'Unione, come indicato di seguito potrebbe funzionare meglio così, provare nel proprio ambiente per determinare quale opzione è migliore.
Un semplice esempio dimostrerà le drastiche differenze si possono vedere in termini di prestazioni:
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
Altri suggerimenti
Se avete intenzione di vedere le differenze di prestazioni, saranno minuto.
Credo che lo stile preferito è
ISNULL(email, '') = ''