パフォーマンスの事実として、どちらが優れていますか? sql-server の実際の 3 つのバージョン (2000/2005/2008) に違いはありますか?
2 に答える
3
フィルターで列をラップするカスタム関数または組み込み関数の使用は絶対に避けてください。これにより、インデックスの使用とシーク可能性に関してオプティマイザーが実行できることが大幅に制限されます。この場合のように、可能な場合は等値演算子と or/union アプローチを使用する習慣を身に付ける必要があります。以下は、 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
于 2009-11-16T22:22:29.860 に答える
0
パフォーマンスの違いが見られる場合、それらはわずかです。
好ましいスタイルは
ISNULL(email, '') = ''
于 2009-11-16T22:00:53.103 に答える