查看复杂数据的替代方案?

时间:2010-12-14 19:31:10

标签: sql sql-server sql-server-2005 tsql triggers

我有一个表,其中包含对查看我的应用程序的用户没用的部分数据。观众希望看到一个类似的表,其中包含所有计算出的值,并且希望能够快速查询该数据。通常,这将是使用View的理想场所。不幸的是,计算的复杂性限制了我对Views的使用,所以我需要一个替代解决方案。我正在考虑做以下事情......

表A包含后端数据。每次更新此表时,触发的触发器都会更新表B,其中显示了这些计算的结果。此时可以快速查询表B.

我唯一担心的是计算过程有点冗长,表A有可能在突发中多次更新。有没有像“之前选择”触发器那样的解决方案?所以基本上表A可以连续多次更新,但只有在查询表B时才会进行计算?

以下是一个示例时间表:

  1. 表A已更新
  2. 表A再次更新[不要运行SP,因为还没有人需要表B数据]
  3. 从表B [运行SP以在获取数据之前更新表B]
  4. 请求数据
  5. 表A已更新
  6. 从表B [运行SP以在获取数据之前更新表B]
  7. 请求数据
  8. 从表B请求数据[不要运行存储过程,因为表B未在表B数据请求之间更新]
  9. 所以我的问题是:

    1. 有什么像我上面描述的那样存在吗?
    2. 如果没有,有没有办法让触发器延迟到完成一批更新/插入之后?表A不会经常修改,所以我可以在更新时使用慢速触发器。唯一的问题是当表A 更新时,它通常一次有数百行,我不想每次都运行慢速触发器。
    3. 感谢任何解决方案/见解!

      编辑 - 关于为什么(我认为至少)触发器实现缓慢的更多细节:

      1. 将发送Update / Insert / Delete语句的应用程序使用LINQ-to-SQL,这对批处理操作不是特别好。因此,如果我想删除一堆记录,它将发送一堆删除语句而不是批量删除语句。有没有办法对delete语句进行分组并在此之后运行触发器? (也许我在这里离主题太远了。)
      2. 我所说的“计算”涉及一些递归函数和一些决策过程。我实际处理的数据是调度数据。因此,表A包含可能有也可能没有预定开始的任务。如果没有定义计划的开始,则必须从其前任计划的开始+其前任持续时间派生它。在某些情况下,前导者也可能没有该信息,因此递归查询一直在挖掘直到找到结果。它并不痛苦,但如果它必须在每次插入/更新/删除时运行,它就会到达那里。我上面提到的“表B”基本上是相同的表,但它已经有计算的预定起始数据(在表A更新时需要更改)。

4 个答案:

答案 0 :(得分:2)

触发器对插入或更新的整批记录进行操作,而不是一次一行。

如果计算花费的时间太长而只有几百条新记录,那么计算本身可能需要进行性能调整。

如果你在触发器中进行计算,那么它们就是每个事务的一部分,并且它们将在允许另一个事务之前完成,因此可以想象它会减慢插入速度。如果你正确地编写了触发器来处理数据集而不是逐行激动,那么它可能不会引起问题。数百行是完成大多数计算的微不足道的数量。如果您批量插入数百万行,我会更关注触发性能干扰其他进程。

您可以创建一个proc来进行计算并将其安排为每十分钟左右运行一次,然后在调用报告时再次运行。通过这种方式,它可以提前进行大部分预先计算,并在报告时捕获最后几个新记录。

给我们一个计算样本和潜在触发器,我们可以更好地帮助您。

如果单个事务进入一个组触发器运行,则无法对一组进行分组。也许你应该停止使用LINQ,如果你需要批量处理,你可以发送一个abatch stament。如果您一次使用多个记录,通常最好使用基于集合的操作。

答案 1 :(得分:2)

我认为物化视图能够解决这个问题,并且运行得相当快。然而,OP没有说出“计算”是什么,只是说它们运行缓慢。因此,这是您最好的选择:

在主表A中添加一个触发器,在该触发器中将受影响行的ID插入到新的“需要完成的工作”表中。由于计算尚未完成,因此开销非常低。

创建一个每x分钟运行一次的作业来进行工作计算并清除“需要完成的工作”表。这项工作将填充并保持与表B保持同步,表B具有最终答案。

仅通过存储过程调用访问“查询”,在此过程中,运行作业使用的处理(将确保表B中的数据是最新的)然后它将使用表B.

答案 2 :(得分:0)

如果可能(当然可能不在您的特定情况下),您可以通过存储过程调用从表B返回数据,而不是从视图/表中选择。这样,只有在专门调用时(即表A已更新后),您的程序才会执行繁重的工作。

答案 3 :(得分:0)

这是对已经讨论过的更简单的变化......

如果您在两个表上都有DeltaTs / EditTs列,则可以:

通过存储过程返回查询数据,该存储过程将检查两个表上的max(Deltats)vs max(deltats)并根据需要更新表b。在更新表A后第一次选择时,你会受到一些打击,但之后它会很好而且很快。