SQL查询性能

亚历克斯

我必须查询一个表,其中包含几百万行的行,并且我想对其进行最优化的查询。

假设我们要控制具有多个放映厅的电影院的访问权限,并保存如下:

AccessRecord
  (TicketId,
   TicketCreationTimestamp,
   TheaterId,
   ShowId,
   MovieId,
   SeatId,
   CheckInTimestamp)

为简化起见,数据类型为“ bigint”和“时间戳”的“ Id”列为“ datetime”。门票随时出售,人们可以随意进入剧院。主键(也是唯一的)是TicketId。

我想为每个电影和剧院及表演(时间)获取访问剧院观看电影的第一个和最后一个人的AccessRecord信息。如果两个签到同时发生,我只需要1个即可。

我的解决方案是在子查询中连接PK和分组列以获取行:

select
  AccessRecord.*
from
  AccessRecord
  inner join(
    select
      MAX(CONVERT(nvarchar(25),CheckInTimestamp, 121) + CONVERT(varchar(25), TicketId)) as MaxKey,
      MIN(CONVERT(nvarchar(25),CheckInTimestamp, 121) + CONVERT(varchar(25), TicketId)) as MinKey
    from
      AccessRecord
    group by
      MovieId,
      TheaterId,
      ShowId
  ) as MaxAccess
    on CONVERT(nvarchar(25),CheckInTimestamp, 121) + CONVERT(varchar(25), TicketId) = MaxKey
    or CONVERT(nvarchar(25),CheckInTimestamp, 121) + CONVERT(varchar(25), TicketId) = MinKey

转换121是对数据时间的规范表达式,其重排方式如下:aaaa-mm-dd hh:mi:ss.mmm(24h),因此按字符串数据类型进行排序,将得到与按日期时间排序相同的结果。

如您所见,这种联接不是非常优化,有什么想法吗?


更新我如何测试不同的解决方案

我已经使用SQL Server 2008 R2在一个具有超过3M行的表的真实数据库中测试了所有答案,以选择正确的答案。

如果我只获得第一个或最后一个访问者:

  • 乔塔拉斯的解决方案持续10秒。
  • GarethD的解决方案持续21秒。

如果我进行相同的访问,但分组列的结果是有序的:

  • 乔塔拉斯的解决方案持续10秒。
  • GarethD的解决方案持续46秒。

如果我同时获得(第一个和最后一个)访问结果的人:

  • 乔·塔拉斯(Joe Taras)(进行工会)的解决方案持续19秒。
  • GarethD的解决方案持续49秒。

其余解决方案(甚至是我的解决方案)在第一次测试中持续超过60秒,因此我取消了它。

乔·塔拉斯

尝试这个:

select a.*
from AccessRecord a
where not exists(
    select 'next'
    from AccessRecord a2
    where a2.movieid = a.movieid
    and a2.theaterid = a.theaterid
    and a2.showid = a.showid
    and a2.checkintimestamp > a.checkintimestamp
)

这样,您就可以为同一部电影前戏选择最后一行作为时间戳。

每行票(我想)是不同的

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章