SQL Server - 上次访问的行时间戳

时间:2012-01-17 10:25:48

标签: sql-server tsql

我有一个用作共享缓存的表,并根据最近是否已访问过各行来定期修剪(即如果该行未在一周内访问,则会被删除)。目前我有一个LastAccessed date列,每次访问该行时都会更新。

目前,我通过UPDATE查询选择并使用OUTPUT子句实际选择数据来执行此操作。但是,这很慢(典型的查询需要几秒钟),我担心锁定和并发访问,因为许多进程可以立即访问此表,并且他们都需要更新上次访问的时间戳。

有更好的方法吗?我知道ROWVERSION,但这似乎是为了更新,而不是选择。将一行写入表中的日期后,它永远不会更改(此时除了LastAccessed列之外)。我似乎也没有任何基于SELECT的触发器。

5 个答案:

答案 0 :(得分:3)

解决性能问题的一种简单方法是更改​​代码,以便仅在LastAccessed date比24小时更早时更新记录。这将大大减少您桌面上发生的更新次数。

总体上更好的方法可能是将LastAccessed date标准化为单独的表,这样您每次阅读时都不必重写整行(通常在您更新整个行时)行被重写某处)。此外,您可以将此更新表设置为一个堆,您只需继续向其中插入新记录,而不是更新以前的记录,这样可以防止发生任何锁定。

将这两者结合起来将解决您的性能问题,除非您的数据很少被访问。这也将解决一般“它锁定整个表”的问题。

对于参考ROWVERSIONTIMESTAMP将无法执行您想要的操作,因为它们不仅仅在UPDATE命令上更新,而且不会映射回任何“日期时间”值。我们不建议您使用您只需编写ROWVERSION to dateGETDATE()的表格进行临时ROWVERSION映射(因为rowversion对于数据库来说是唯一的)。

答案 1 :(得分:0)

ROWVERSION列会在每次更新时自动更新 - 但包含有关该更新日期或时间的任何信息(仅 a反击 - 与日期/时间完全没有关系!)。

不幸的是 - 目前在SQL Server中没有自动“开箱即用”的解决方案 - 没有神奇的方法来跟踪更新的最后日期/时间。如果您需要这些信息 - 您需要自己保留。只有其他选项:使用ON UPDATE触发器来处理这个问题 - 所以你不必记得在每个UPDATE语句中都这样做......

更新:啊 - 好吧,所以你想在SELECT期间更新这个 - 这在SQL Server目前是绝对不可能的 - 根本没有ON SELECT触发机制可用,所以我不认为你可以用SELECT来跟踪“上次访问”,而不是自己为每个SELECT语句手动执行此操作.....

答案 2 :(得分:0)

本机Sql Server工具无法实现,您可以通过存储过程执行自己的数据访问来实现非常有限的方式

答案 3 :(得分:0)

这很困难,但有可能。

  • 创建一个server side trace过滤此表(在字段object_id上)并将结果写入表
  • 在跟踪结果表上写一个INSTEAD OF触发器,该表触发以跟踪文本和时间戳作为参数的TSQL或CLR proc。
  • 解析跟踪文本,并将SELECT xxx部分替换为UPDATE myTable SET lastAccessed = @timestamp
  • 执行生成的TSQL语句。

这会有效,但这是否意味着你应该这样做?如果您希望使用缓存系统,我认为您最好使用真正的缓存。 SQL Server提供完整的ACID,这对缓存的要求太高。 (当服务器崩溃时,您通常不介意需要重新填充缓存)

答案 4 :(得分:0)

如果您使用的是SQL Server 2008,可能需要查看“更改跟踪” - http://msdn.microsoft.com/en-us/library/bb933875.aspx