在SQL

时间:2016-03-07 11:41:10

标签: sql sql-server

我们的组织有一个报告应用程序,它查询实时事务表以提取报告数据。由于查询针对的是不断更新的事务表,因此报表性能令人沮丧。我们正在尝试提出一种新的数据库设计来提高性能。

我的想法是每年有三个不同的表格(例如; reports_2014,reports_2015,reports_2016)(因为我们只需要报告最近三年的数据),这些表格将在年底从实时创建D B。报告数据库上的当前年份表(reports_2016)将使用前一天午夜的新记录进行更新。我的报告查询将使用一个视图,它将是所有这三个表的联合+来自实时表的数据,用于记录从午夜到此时的记录。

最初,我认为这是一个很好的设计,只要我在这些历史表上有好的索引。

但是,我有一个问题来自于更新这些实时表的固有应用程序设计。 如果我取消交易,交易记录的状态列可以更改为取消,以及新的交易取消记录。 我可以通过使用AFTER插入触发器并捕获正确的更新来捕获它。

现在的问题是,在我的ETL将最后几天数据复制到历史记录表的过程中发布了取消记录时,我错过了更新。

我如何捕获这个?有没有办法延迟触发器直到我的ETL完成?或者有更好的方法解决这个问题吗?

如果这不是发布此问题的正确位置,我表示道歉。

谢谢, Roopesh

2 个答案:

答案 0 :(得分:3)

具有相同结构的多个并行表几乎不是数据库设计的好主意。数据库提供了两种处理性能的重要方法:

  • 索引
  • 分区

以及其他方法,例如重写查询,空间索引,全文索引等。

在您的情况下,请考虑表分区而不是多个表。

对于您的流程,您应该使用记录的创建/修改日期。我会设想一个早上凌晨1点运行的工作,这项工作将收集前一天的记录。午夜后的任何更改都不适用。他们将在第二天被收录。

如果报告也需要实时,那么您应该考虑将报告构建到应用程序本身。一些方法是:

  • 采用与上述相同的方法,但报告的运行频率更高(例如每小时一次,而不是每天一次)。
  • 修改现有触发器以处理对报告表和基表的更新。
  • 在处理事务表和报告表的存储过程中包装所有DML事务。
  • 重新构建系统以使用具有多个读取器的队列来处理不同的处理需求。

答案 1 :(得分:0)

感谢Gordon的投入。在这一点上,我们是一个实时报告系统。数据库是生产事务数据库的镜像实例。每当向生产数据库输入新事务时,相同的记录立即流向具有完全相似模式的报告数据库。我们确实在经常查询的列上有索引,但是由于每小时都有很多插入,因此索引性能会降低很快。我们在两周内重建一次,大约需要8个小时。这就是我认为在这个巨大的交易表上有索引每小时有很多插入可能不是一个好主意..如果我错了请纠正我...

我实际上正在阅读分区,看看它是否适合我。我和我们的DBA讨论过相同的问题,我得到了以下评论'报告数据库是实时生产数据库的镜像实例。您必须在生产事务数据库上实现分区。如果您在镜像实例上使用分区,而该镜像实例不能用作实际源,则DB不会被分区' 我不确定这是多少。你知道分区和镜像之间是否存在这种依赖性?