繁体   English   中英

SQL-查找序列/路径

[英]SQL - finding Sequence / Path

我有一个大事件发生表。 它包含以下列:

  • 用户身份
  • EventId(事件类型)
  • 时间戳记(发生此事件时)

我想知道所有在日期范围之间执行某些事件序列的用户。

如果我正在寻找事件序列1-2-3 ...,那么事件1应该在2之前发生,事件2应该在3之前发生。

目前,我只是使用CLR存储的proc遍历记录集。 这种方法很慢。 在SQL中有更好的方法吗?

我正在使用SQl Server2008。每个userId可能有重复的eventId。

该表的大小大约为3到4十亿行,日期范围可能包含约10亿行。 性能至关重要。

谢谢

如果您可以预先知道要查找的序列,而且时间不会太长,则可以选择所需表的子集(以处理日期范围,并选择一个事件ID),并加入尽可能多的本身需要,然后在其中选择date(event1)> date(event2)和date(event2)> date(event3)的行。 这将是一个相当长的查询,这就是为什么我不键入它,但是应该在不会低效的情况下工作的原因。

编辑:示例:

SELECT a.userID,a.date,b.date,c.date FROM
    (SELECT * FROM `events` WHERE `date` BETWEEN $date1 AND $date2 AND `type`=$type1) a
    LEFT JOIN (SELECT * FROM `events` WHERE `date` BETWEEN $date1 AND $date2 AND `type`=$type2) b ON a.userID=b.userID
    LEFT JOIN (SELECT * FROM `events` WHERE `date` BETWEEN $date1 AND $date2 AND `type`=$type3) c ON a.userID=c.userID
    WHERE a.date > b.date AND b.date > c.date

假设您知道在编写查询时的确切顺序(无论是在编码时,还是在调用者代码动态生成查询时),只要顺序不太长,就可以执行此操作:

select *
from eventTable1 T1, eventTable1 T2, eventTable1 T3,
where t1.theTime between '01/01/2000' and '01/01/2001'
  and t2.theTime between '01/01/2000' and '01/01/2001'
  and t3.theTime between '01/01/2000' and '01/01/2001'
  and t1.theTime <= t2.theTime
  and t2.theTime <= t3.theTime
  and t1.eventId = 1
  and t2.eventId = 2
  and t3.eventId = 3
  and t1.userId = t2.userId
  and t1.userId = t3.userId
  and t2.userId = t3.userId -- Needed for performance reasons

如果您在userId, theTime上有一个索引并且在给定的时间段内行数是可管理的(例如,您无法获得一组用户的全部十亿行) userId, theTime那么这将很好地工作

请注意,可以根据您的数据集和时间跨度进一步优化上述内容(可能应该),方法是先将给定时间跨度的所有记录选择到临时表中,然后对临时表进行上述连接。 这种优化效果最好,如果排在给定的时间跨度量是可控的(如<100K?),而且是在一个索引theTime


另一种方法可能是避免JOIN并简单地按用户检索组合的所有序列; 然后在调用方代码中执行“此序列正确吗”:

SELECT * FROM eventTable
ORDER BY userId, theTime   -- works MUCH better if this is an covering index

然后在调用者代码中,您基本上对每个用户序列进行了子集匹配(对我来说似乎微不足道,但是如果不确定如何随意询问,请随意询问)

由于这几乎是每个用户的处理,因此可以通过选择用户块来避免耗尽内存(每个用户大约事件数,然后尽可能多地获取对您的内存安全的用户)以使SQL快速运行必须支持“ TOP”或“ LIMIT”语法,并且您应该在临时表中具有所有用户的预建列表。

像这样吗


select userid, eventid, theTime 
from eventTable 
where theTime between '01/01/2000' and '01/01/2001'
order by theTime DESC 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM