Fab*_*ied 15 sql-server sql-server-2012 change-tracking
在我的应用程序中,有一个运行在 SQL Server 2012 上的数据库,我有一个作业(计划任务),它定期执行一个昂贵的查询并将结果写入一个表,稍后可以由应用程序查询。
理想情况下,我只想在自上次执行查询后发生更改时运行该昂贵的查询。由于源表非常大,我不能只选择所有候选列的校验和或类似的东西。
我有以下想法:
但是,我真的很想知道是否有一种轻量级的方法来检测表上的更改,而无需我明确跟踪写入。例如,我可以获取ROWVERSION
表格的“当前”或类似的信息吗?
Rem*_*anu 15
不,没有。任何类型的“上次更新时间”跟踪都会遇到严重的性能问题,因为来自所有事务的所有更新都将尝试更新跟踪“上次更新时间”的记录。这实际上意味着任何时候只有一个事务可以更新表,所有其他事务都必须等待第一个事务提交。完整的序列化。愿意忍受这种性能损失的管理员/开发人员的数量可能很少。
因此,您不得不通过自定义代码来处理它。这意味着触发器,因为替代方案(从日志记录中检测)是仅为事务复制(或者它是CDC的另一个自我)保留的特权。请注意,如果您尝试通过“上次更新时间”列跟踪它,那么您将面临上述序列化问题。如果更新并发性很重要,那么您必须使用队列机制(触发器使用 INSERT,然后一个进程聚合插入的值以制定“上次更新时间”)。不要试图用一些“聪明”的解决方案作弊,比如偷偷摸摸当前的身份或查找sys.dm_db_index_usage_stats。还有一个'updated_at' per-record 列,就像 Rails 时间戳一样,
有什么“轻量级”的选择吗?实际上有一个,但很难说它是否适合你,也很难做到正确:Query Notifications。查询通知正是这样做的,如果任何数据发生更改并且您需要刷新查询,它将设置通知。尽管大多数开发人员只熟悉其作为 SqlDependency 的 .Net 化身,但 Query Notification可以用作检测数据更改的长期存在的持久机制。与真正的更改跟踪相比,它将非常轻量级,并且其语义更接近您的需求(某事,任何事,已更改,因此您需要重新运行查询)。
但最终,在你的位置上,我真的会重新考虑我的假设并回到绘图板。也许您可以使用日志传送或复制在不同的服务器上设置报告数据库。我在字里行间读到的是你需要一个合适的 ETL 管道和一个分析数据仓库......
小智 8
看起来我在这里玩游戏晚了两年,但确实有一种非常轻巧的方式来完成您的要求。
有两种 SQL Server 机制可以帮助您。您的最终解决方案可能是两者的混合。
更改跟踪。SQL Server 能够将特定表置于监视之下,仅记录哪些行发生了更改(通过它们的主键值)以及更改的类型(插入、更新或删除)。在对一组表设置更改检测后,轻量级查询可以告诉您自上次检查以来是否对表进行了任何更改。开销与维护额外的简单索引大致相同。
行版本/时间戳。这是一个 8 字节的 varbinary 列类型(可转换为 BigInt),每当插入或更新包含一个的行(它对删除没有帮助)时,它都会在数据库范围内递增。如果对这些列进行索引,则可以通过将 MAX(timestamp) 与其自上次评估以来的值进行比较来轻松判断行数据是否已更改。由于该值是单调递增的,如果新值大于您上次检查它时的值,这将为您提供数据已更改的可靠指示。
如果源是仅插入的,则给它一IDENTITY
列。当您进行数据传输时,您会记录写入的最高值。在下一次传输期间,您只需要查询大于上一次传输期间记录的值。我们这样做是为了将日志记录传输到数据仓库。
对于可更新的行,添加一个“脏”标志。它将具有三个值 - 干净、脏和已删除。日常查询必须省略标志设置为“已删除”的行。这在维护、测试和运行时将是昂贵的。在大查询之后,您提到必须删除标记为删除的所有行,并为所有其他行重置标志。这不会很好地扩展。
Change Data Capture 的一个更轻松的替代方案是Change Tracking。它不会告诉您更改了哪些值,只会告诉您该行自上次查询以来已更改。内置功能便于检索更改的值和跟踪管理。我们已经成功地使用 CT 在 100,000,000 行表中每天处理大约 100,000 次更改。
查询通知的作用仍然更高——在结果集的级别。从概念上讲,这就像定义一个视图。如果 SQL Server 检测到通过该视图返回的任何行已更改,它就会向应用程序发送一条消息。没有指示更改了多少行或哪些列。只有一条简单的消息说“发生了一些事情”。由应用程序进行查询和反应。实际上,正如您想象的那样,它比这复杂得多。关于如何定义查询和通知可能会针对更改数据以外的条件触发的限制。当通知触发时,它会被删除。如果随后发生进一步的感兴趣的活动,则不会发送进一步的消息。
在 OP 问题的上下文中,QN 将具有设置开销低和运行时间成本低的优势。建立和维护严格的订阅-消息-反应机制可能需要付出巨大的努力。由于数据表很大,它可能会经常更改,这意味着在大多数处理周期中可能会触发通知。因为没有迹象表明增量处理发生了什么变化是不可能的,就像 CT 或 CDC 那样。由于错误触发造成的开销是令人厌烦的,但即使在最坏的情况下,昂贵的查询也不需要比当前更频繁地运行。
归档时间: |
|
查看次数: |
80395 次 |
最近记录: |