SqlDependency性能

9
我有一个使用SQL Server数据库的Web应用程序,该数据库与其他Web应用程序共享(我无法控制)。我必须知道任何Web应用程序何时对数据库中的某些表进行更改。
我的第一个想法是使用 SqlDependency (特别是{{link1: SqlTableDependency }},因为我需要知道更改的数据),但我担心会出现性能问题。
我想知道是否有关于 SqlDependency (而不是 SqlTableDependency ),触发器(触发WS、exe等)和轮询的性能比较。
我找到了一些问题和文章,但它们对我来说不够清楚。

其他信息:

  • 需要监控五个表格
  • 每个表格每秒大约有一次变化
  • 每天表格增加约100行

谢谢!


1
注意:如果您计划在SQL Azure中使用SqlDependency,则除非您拥有自己的托管实例,否则它将无法正常工作。https://dev59.com/8Jfga4cB1Zd3GeqPALtR - Simon_Weaver
2个回答

7
简短的回答是......在实施之前,直接比较性能可能涉及太多变动因素。我将谈论性能,但同时需要确定哪些选项满足我们应用程序的基本需求。

SqlDependency与SqlTableDependency和触发器的区别

虽然SqlDependencySqlTableDependency在名称上相似,但它们的行为和实现的结果非常不同。与SqlDependency不同,SqlTableDependency会使用其他数据库对象来补充队列,即针对目标表的触发器。

在我的应用程序中,处理从服务器到客户端的SignalR消息时,SqlDependency是一个无法启动的选项,因为仅靠它本身无法提供我需要的实时数据以读取来自数据库的更改。公平地说,它并不是被设计成这样。任何数据都需要通过单独的数据库调用来获取。因此,任何效率或感知速度都几乎被抵消了。如果数据更改频繁,并且没有足够的解决方法,则在更改通知后立即调用过程甚至可能无法带回我们正在寻找的数据。

这样的砖墙促使我实施了SqlTableDependency。文档可能不会立即清楚地表明SqlTableDependency在启动时自动填充数据库对象。因此,我们不必花费时间编写Sql过程。主要的免责声明是,您的DBA不仅必须支持设置DB代理启用,还需要权限创建和删除触发器。必须小心停止SqlTableDependency,否则触发器将必须从数据库中手动清除。如果您想保证性能差,就在一个表上留下几十个触发器!通知不仅需要更长时间,而且查询数据的任何人都会遇到减速。
话虽如此,我们只需要一个SqlTableDependency触发器就可以向成千上万的客户端发送消息或将数据发送到所需的许多服务。从这个角度来看,我认为它是有效的。
这是SqlTableDependency文档中有关性能的简要提及:

负载测试和性能 SqlTableDependency支持每50毫秒执行的DML触发的通知。使用两个客户端应用程序同时在同一表上执行10,000个随机插入/更新/操作进行的测试。(https://github.com/christiandelbianco/monitor-table-change-with-sqltabledependency)


轮询

可以设置一个服务来轮询需要监视的5个表。但是,根据我们是否需要在每次更改时处理数据,或者我们只需要知道有什么变化,我估计使用轮询处理数据会变得很麻烦,特别是在如此频繁的情况下(按你的估计每秒1次)。


建议

尽可能创建多种实现方法,并观察每个方法的行为。在任何负载测试之前,有些方法将被排除在外。 SqlTableDependency 是一个很好的起点。

每种方法都有独特的实现方式,因此性能基准必须考虑支持代码和数据环境对整体情况的影响。


如果我有一个拥有100万行的表格,这个系统会检索所有100万行以便跟踪该表格的数据更改,是吗? - vpetrovic
@vpetrovic 不,它只是创建了监视任何更改的数据库触发器。SqlTableDependency 的源代码可能会有所帮助 https://github.com/canadelinc/sqltabledependency/blob/master/TableDependency.SqlClient/SqlTableDependency.cs - Simon_Weaver
请注意,SqlTableDependency(不是由微软提供)甚至不会内部使用Microsoft的SqlDependency。我原以为它会,但在github中搜索并没有发现任何使用它的情况。 - Simon_Weaver
SQL Server 把为 SqlTableDependency 创建的触发器存储在哪里? - Tim

5

正如MTADEV所说:“也就是说,我们只需要一个SqlTableDependency触发器即可向成千上万的客户端发送消息或将数据发送到尽可能多的服务。从这个角度来看,我认为它是高效的。”。

当您需要在多个客户端上发送通知更改时,您必须创建一个持有SqlTableDependency的中央服务。由SqlTableDependency传递的每个通知都将由此服务管理,而该服务将通知其他客户端:

enter image description here

请查看:https://stockprices.codeplex.com/

有没有一种方法可以让SqlTableDependency为所有客户端使用现有的触发器和队列?我的经验是每个SqlDependency客户端使用一个新的触发器,这会极大地影响性能。 - Jins Peter
我指的是当然没有中央服务。 - Jins Peter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接