Domanda

come un fatto di prestazioni, che uno è meglio? C'è una differenza tra l'attuale 3 tre versioni di SQL server (2000/2005/2008)?

È stato utile?

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, '') = ''
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top