针对这个问题,不能下绝对的定论,
在 SQL Server 中,临时表和物理表的性能差异通常取决于具体的使用场景和数据量。
临时表存储在 tempdb 数据库中,并在使用后自动清理。对于处理小批量数据或需要隔离数据的场景,临时表通常可以提供较好的性能。临时表还可以用于存储中间结果,避免在复杂查询中重复计算。
物理表,又称为永久表,存储在用户数据库中,需要手动进行创建和删除。物理表通常用于存储大量的、持久的数据。对于大批量数据的操作,物理表通常可以提供更好的性能,因为它们可以利用更多的索引和优化策略。
但是,无论是临时表还是物理表,都需要合理地设计表结构和索引,以及优化查询语句,才能实现最佳性能。在选择使用临时表还是物理表时,需要考虑数据的大小、生命周期、访问模式等因素。
总的来说,临时表和物理表各有优势,需要根据具体的需求和场景来选择。在某些情况下,可能需要同时使用临时表和物理表,以实现最佳性能。
为啥写这个,因为我在数据库中使用到了算法,最开始本地用样本数据测试后效果是不错的,速度也很快,但是用上真实数据后,数据量是百万级别的,那问题就大了,所以 1,必须优化sql的计算方法,2,在ETL中处理计算不是一个明智的方式,可以把要计算的值保存在物料表中!
可以共享出我这个算法,是计算 加权平均数的算法
USE [YY_DW]
GO
/****** Object: StoredProcedure [dbo].[P_getJCL]
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[P_getJCL_new]
@speedName varchar(50),
@sdate datetime,
@OutputRes decimal(18,4) OUTPUT
as
begin
declare @res decimal(18,4)=0; --返回数据
declare @avg1 decimal(18,2)=0; --平均值
declare @count int=0; --数量
--1 计算平均值 前半个小时的数据
declare @beforeDate datetime = dateadd(MI,-30,@sdate);
--查询不到数据返回 值为 -1
if (not exists(select 1 from V_speetab_ALL_DW where [speeName]=@speedName and createtime>= @beforeDate and createtime<@sdate group by [speeName]))
begin
set @OutputRes=-1;
return;
end
select @count=count([speed]) , @avg1=AVG([speed]) from V_speetab_ALL_DW d where [speeName]= @speedName and createtime>= @beforeDate and createtime<@sdate
group by [speeName];
--2 权数
declare @qs decimal(18,7)=0;
select @qs=2700*3.14159 / @avg1
set @qs= CAST(@qs as decimal(18,0)) --取整,四舍五入 55
declare @newqs int=0;
set @newqs= CAST(@qs as int); --处理为整数,不带小数 直接转 int 不会四舍五入
--临时表#Tmp 存储加权计算后的数据
----drop table #Tmp --删除临时表#Tmp
if object_id(N'tempdb..#Tmp',N'U') is not null
begin
DROP Table #Tmp
end
create table #Tmp --创建临时表#Tmp
(
ID int IDENTITY (1,1) not null, --创建列ID,并且每次新增一条记录就会加1
JS decimal(18,2), --处理后的数据
primary key (ID) --定义ID为临时表#Tmp的主键
);
----表中存在数据,清空
--if exists(select 1 from [YY2FSC_DW].[dbo].[TB_XSD_Temp] )
-- begin
-- truncate table [YY2FSC_DW].[dbo].[TB_XSD_Temp]
-- end
--临时表#Tmp 存储加权计算后的数据
--drop table #Tmp --删除临时表#Tmp
if object_id(N'tempdb..#Tmp_sd',N'U') is not null
begin
DROP Table #Tmp_sd
end
create table #Tmp_sd --创建临时表 #Tmp_sd
(
num int, --创建列ID,并且每次新增一条记录就会加1
speed decimal(18,4) --处理后的数据
);
insert #Tmp_sd (num,speed)
select row_number() over(partition by [speeName] order by [createtime] ) as [num],[speed]
from V_speetab_ALL_DW d where d.[speeName]= @speedName and d.[createtime]>= @beforeDate and d.[createtime]<@sdate
set @count=@count-@newqs+1;
--循环遍历修改记录--
declare @tempSpeed decimal(18,4)=0;
declare @i int=0;
while @i<@count
begin
select @tempSpeed= AVG([speed]) from
(
select [num],[speed] from #Tmp_sd
) t
where @i< t.num and t.num<= (@newqs+@i)
insert into #Tmp (JS) values (@tempSpeed);
set @i=@i +1
end
--计算临时表中的数据
select @res= ((MAX([JS]) - min([JS])) / AVG([JS])) * 100 from #Tmp
--select @res= ((MAX([JS]) - min([JS])) / AVG([JS])) * 100 from [YY2FSC_DW].[dbo].[TB_XSD_Temp]
SET @OutputRes = @res;
select @OutputRes res
--调用方式
--DECLARE @OutputValue decimal(18,4);
--EXEC [dbo].[P_getJCL] 'spee1', '2023-06-01 00:00:00.000' , @OutputValue OUTPUT;
--select @OutputValue
end;
用数据库定时作业去处理这个事情就可以了!