我有一个用作共享缓存的表,并根据最近是否已访问过各行来定期修剪(即如果该行未在一周内访问,则会被删除)。目前我有一个LastAccessed date
列,每次访问该行时都会更新。
目前,我通过UPDATE
查询选择并使用OUTPUT
子句实际选择数据来执行此操作。但是,这很慢(典型的查询需要几秒钟),我担心锁定和并发访问,因为许多进程可以立即访问此表,并且他们都需要更新上次访问的时间戳。
有更好的方法吗?我知道ROWVERSION
,但这似乎是为了更新,而不是选择。将一行写入表中的日期后,它永远不会更改(此时除了LastAccessed
列之外)。我似乎也没有任何基于SELECT
的触发器。
答案 0 :(得分:3)
解决性能问题的一种简单方法是更改代码,以便仅在LastAccessed date
比24小时更早时更新记录。这将大大减少您桌面上发生的更新次数。
总体上更好的方法可能是将LastAccessed date
标准化为单独的表,这样您每次阅读时都不必重写整行(通常在您更新整个行时)行被重写某处)。此外,您可以将此更新表设置为一个堆,您只需继续向其中插入新记录,而不是更新以前的记录,这样可以防止发生任何锁定。
将这两者结合起来将解决您的性能问题,除非您的数据很少被访问。这也将解决一般“它锁定整个表”的问题。
对于参考ROWVERSION
而TIMESTAMP
将无法执行您想要的操作,因为它们不仅仅在UPDATE
命令上更新,而且不会映射回任何“日期时间”值。我们不建议您使用您只需编写ROWVERSION to date
和GETDATE()
的表格进行临时ROWVERSION
映射(因为rowversion对于数据库来说是唯一的)。
答案 1 :(得分:0)
ROWVERSION
列会在每次更新时自动更新 - 但不包含有关该更新日期或时间的任何信息(仅 a反击 - 与日期/时间完全没有关系!)。
不幸的是 - 目前在SQL Server中没有自动“开箱即用”的解决方案 - 没有神奇的方法来跟踪更新的最后日期/时间。如果您需要这些信息 - 您需要自己保留。只有其他选项:使用ON UPDATE
触发器来处理这个问题 - 所以你不必记得在每个UPDATE
语句中都这样做......
更新:啊 - 好吧,所以你想在SELECT
期间更新这个 - 这在SQL Server目前是绝对不可能的 - 根本没有ON SELECT
触发机制可用,所以我不认为你可以用SELECT
来跟踪“上次访问”,而不是自己为每个SELECT
语句手动执行此操作.....
答案 2 :(得分:0)
本机Sql Server工具无法实现,但您可以通过存储过程执行自己的数据访问来实现非常有限的方式
答案 3 :(得分:0)
这很困难,但有可能。
INSTEAD OF
触发器,该表触发以跟踪文本和时间戳作为参数的TSQL或CLR proc。SELECT xxx
部分替换为UPDATE myTable SET lastAccessed = @timestamp
这会有效,但这是否意味着你应该这样做?如果您希望使用缓存系统,我认为您最好使用真正的缓存。 SQL Server提供完整的ACID,这对缓存的要求太高。 (当服务器崩溃时,您通常不介意需要重新填充缓存)
答案 4 :(得分:0)
如果您使用的是SQL Server 2008,可能需要查看“更改跟踪” - http://msdn.microsoft.com/en-us/library/bb933875.aspx