在大型数据集中查找给定查找日期的上次已知出现

时间:2012-08-28 13:37:25

标签: sql-server postgresql database-design

我有一个特定的设计问题一直困扰着我。 我有一个大型的实时GPS位置日志表,其中包含数千个资产的点条目。点数每个资产每天数百个点进入数据库。我有一个索引IX(资产asc,EventTime asc)来加速目标资产的点查询。我有一个LastKnownLocation表,用于将每个资产与其最重要的点相关联。这只为我提供了CURRENT最后一次已知的查找。 我的问题是,有没有人知道在给定许多资产的特定查找日期的情况下,能够查询位置日志表以查找最后已知位置的有效方法? “问:2012年7月1日结束的所有资产在哪里”

BTW,由于每个资产都使用自己的内部单调事件时间戳来报告其点,因此与每个资产相关的表的LocationLog.LocationLogID auto inc主键存在隐含的单调关系。这就是我可以使用MAX Aggregate的原因。

SELECT MAX(LocationLog.LocationLogID) FROM LocationLog 
WHERE LocationLog.fk_AssetID IN 
(
    //LIST OF required assets for report
) 
AND LocationLog.EventTime <= '2012/07/01 23:59:59'
GROUP BY LocationLog.fk_AssetID

问题是数据库索引IX可以快速访问单个资产的所有点。然后,这些点按索引中的事件时间排序,因此dbengine可能会在索引中的事件时间内执行数据扫描,以查找日期为&lt; =查找日期的最大LocationLogID。自资产在查找日期之前报告以来的时间越长,查找匹配的扫描时间越长。

由于我的位置日志是9000多万行,并且增长1000资产查询需要50秒。

查找给定查找日期的最后一次已知事件必须是一个众所周知的设计模式,但它不会影响我的搜索。

PS:运行MSSQL2000,但迁移到Postgres

2 个答案:

答案 0 :(得分:1)

消除 IN(...)

可能会有所帮助

尝试类似

的内容
--
--  index on AssetID, EventTime desc
--
select
      AssetID
    , LocationID
    , EventTime
from LocationLog as a
join (
        select AssetID_1
        union
        select AssetID_2
        union
        select AssetID_3
        -- etc, list of assets needed in report
      ) as b on b.AssetID = a.AssetID
where a.EventTime = (select max(xx.EventTime) 
                       from LocationLog as xx 
                      where xx.AssetID = a.AssetID
                        and xx.EventTime <= '2012-08-28 12:05:00')
;

答案 1 :(得分:0)

我想到了两件事:

  • 维护您所在位置的物化视图,存储每天每个资产的日终位置;或
  • 分区,分区,分区!例如,如果您在每个分区中只有一周的数据,那么此类搜索会便宜得多。

我可能会创建一个end_of_day_location表,而不是在每天结束时清除我的last_known_location表,而是先将INSERT内容end_of_day_location放入{{1}}