Bu benim SQL Server 2012 RTM'deki sınavım.
if object_id('tempdb..#temp1') is not null drop table #temp1;
if object_id('tempdb..#timer') is not null drop table #timer;
if object_id('tempdb..#bigtimer') is not null drop table #bigtimer;
GO
select a.*
into #temp1
from master..spt_values a
join master..spt_values b on b.type='p' and b.number < 1000;
alter table #temp1 add id int identity(10,20) primary key clustered;
create table #timer (
id int identity primary key,
which bit not null,
started datetime2 not null,
completed datetime2 not null,
);
create table #bigtimer (
id int identity primary key,
which bit not null,
started datetime2 not null,
completed datetime2 not null,
);
GO
--set ansi_warnings on;
set nocount on;
dbcc dropcleanbuffers with NO_INFOMSGS;
dbcc freeproccache with NO_INFOMSGS;
declare @bigstart datetime2;
declare @start datetime2, @dump bigint, @counter int;
set @bigstart = sysdatetime();
set @counter = 1;
while @counter <= 100
begin
set @start = sysdatetime();
select @dump = count(case when number < 100 then 1 end) from #temp1;
insert #timer values (0, @start, sysdatetime());
set @counter += 1;
end;
insert #bigtimer values (0, @bigstart, sysdatetime());
set nocount off;
GO
set nocount on;
dbcc dropcleanbuffers with NO_INFOMSGS;
dbcc freeproccache with NO_INFOMSGS;
declare @bigstart datetime2;
declare @start datetime2, @dump bigint, @counter int;
set @bigstart = sysdatetime();
set @counter = 1;
while @counter <= 100
begin
set @start = sysdatetime();
select @dump = SUM(case when number < 100 then 1 else 0 end) from #temp1;
insert #timer values (1, @start, sysdatetime());
set @counter += 1;
end;
insert #bigtimer values (1, @bigstart, sysdatetime());
set nocount off;
GO
Bireysel koşulara ve partilere ayrı ayrı bakmak
select which, min(datediff(mcs, started, completed)), max(datediff(mcs, started, completed)),
avg(datediff(mcs, started, completed))
from #timer group by which
select which, min(datediff(mcs, started, completed)), max(datediff(mcs, started, completed)),
avg(datediff(mcs, started, completed))
from #bigtimer group by which
5 kez çalıştırdıktan sonra (ve tekrarlayan) sonuçlar oldukça yetersizdir.
which ** Individual
----- ----------- ----------- -----------
0 93600 187201 103927
1 93600 187201 103864
which ** Batch
----- ----------- ----------- -----------
0 10108817 10545619 10398978
1 10327219 10498818 10386498
Çalışma koşullarında, SQL Server zamanlayıcısının ayrıntı derecesine göre ölçüldüğünde uygulama arasında farklılık olduğundan çok daha fazla değişkenlik olduğunu gösterir. Her iki sürüm de üst sıralarda olabilir ve sahip olduğum maksimum varyans% 2,5'tir.
Ancak, farklı bir yaklaşım benimsemek:
set showplan_text on;
GO
select SUM(case when number < 100 then 1 else 0 end) from #temp1;
select count(case when number < 100 then 1 end) from #temp1;
StmtText (SUM)
|--Compute Scalar(DEFINE:([Expr1003]=CASE WHEN [Expr1011]=(0) THEN NULL ELSE [Expr1012] END))
|--Stream Aggregate(DEFINE:([Expr1011]=Count(*), [Expr1012]=SUM([Expr1004])))
|--Compute Scalar(DEFINE:([Expr1004]=CASE WHEN [tempdb].[dbo].[#temp1].[number]<(100) THEN (1) ELSE (0) END))
|--Clustered Index Scan(OBJECT:([tempdb].[dbo].[#temp1]))
StmtText (COUNT)
|--Compute Scalar(DEFINE:([Expr1003]=CONVERT_IMPLICIT(int,[Expr1008],0)))
|--Stream Aggregate(DEFINE:([Expr1008]=COUNT([Expr1004])))
|--Compute Scalar(DEFINE:([Expr1004]=CASE WHEN [tempdb].[dbo].[#temp1].[number]<(100) THEN (1) ELSE NULL END))
|--Clustered Index Scan(OBJECT:([tempdb].[dbo].[#temp1]))
Benim okumaya göre, SUM versiyonunun biraz daha fazlasını yaptığı anlaşılıyor. TOPLA ek olarak bir COUNT gerçekleştiriyor . Bunu söyledikten sonra COUNT(*)
farklıdır ve daha hızlı olması gerekir COUNT([Expr1004])
(NULL atla, daha fazla mantık). Makul iyileştirici fark edecektir [Expr1004]
içindeSUM([Expr1004])
SUM sürümü "int" tipi olduğu ve bu yüzden bir tamsayı kayıt kullanmaktadır.
Her durumda, COUNT
sürümün çoğu RDBMS'de daha hızlı olacağına inanıyorum, ancak testten elde ettiğim sonuç SUM(.. 1.. 0..)
, gelecekte en azından SQL Server için ANSI UYARILARINI kullanırken ortaya çıkan herhangi bir sebep olmadan sebep olacağım. COUNT
.