天天看點

大資料量下的查找最新的幾條資料的通用方法

由于項目需要,需要擷取一組資料的的最新一條資料,表結構如下:

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/

繼續閱讀