由于项目需要,需要获取一组数据的的最新一条数据,表结构如下:
create table [dbo].[wusu_suolitest_table](
[id] [bigint] identity(1,1) not null,
[receivetime] [datetime] null,
[groupid] [bigint] not null,
[datavalue] [float] null,
[sensorcode] [char](10) not null,
)
在这个表上只有两种操作,插入和查询,没有删除和更新。而且同一种设备,随着id列的变大,receivetime也随着变大。
每一个不同的sensorcode代表了一个设备,目前有50个设备,每30秒上报一次数据,receivetime代表上报数据的时间,现在需要获取每一个设备最新一次的数据,
开始我使用如下的查询语句:
select * from wusu_suolitest_table where id in (select max(id) from wusu_suolitest_table group by sensorcode )
在数据量比较小时,是没有问题的,但数据量特别大时,这种方式,目前一天的数据就超过了14万,有很大的延时,即使在id上有聚集索引,sensorcode上使用了分区,依然没有多大作用。时间主要花费到了group by上。
实在想不多到什么好的而解决方法,就只能在此表上创建一个触发器,每次插入数据时就把最新的数据放在了一个临时表,又由于临时表最多只有50条数据,速度当然就很好了。
create trigger [dbo].[updatewusu_lastoriginaldatasuoli]
on [dbo].[wusu_suolitest_table]
after insert
as
begin
declare @sensorcode char(10), @datavalue float ,@receivetime datetime ,@groupid bigint
select @sensorcode=sensorcode,@datavalue=datavalue,@receivetime=receivetime,@groupid=groupid from inserted
update wusu_lastoriginaldata set datavalue=@datavalue,receivetime=@receivetime,groupid=@groupid
where sensorcode=@sensorcode
end
当然这是为了获取各种设备最新的一条数据,如果要获取最新的两条数据,最多也就是100条记录,一次类推,只需要把上边的触发器修改一下就可以。
但还有没有更好的方式,在不修改表结构的情况下?目前还没有想到。
有人提供了使用关联子查询的方式,确实比group by好多了,但当数据量大时,十天的数据,依然会很慢,大约20多秒。
select * from wusu_suolitest_table as t
where id = (select max(id) from wusu_suolitest_table where sensorcode=t.sensorcode )
====================================分割线================================
最新内容请见作者的github页:http://qaseven.github.io/