如何确定何时创建新表来保存可以从查询中获取的数据?

Rac*_*hel 8 performance sql-server-2005 sql-server query-performance

我们有一张付款表,代理商会收到付款佣金。佣金取决于几个不同的因素,例如收到付款需要多长时间,因此在计算代理获得的佣金率时会涉及一些计算,但并不复杂。

例如,它可能永远不会比这更复杂:

SELECT Payments.Amount * CASE 
    WHEN DateDiff(year, Client.Received, Payments.DatePaid) = 1 THEN Rates.Rate1
    WHEN DateDiff(year, Client.Received, Payments.DatePaid) = 2 THEN Rates.Rate2
    ELSE Rates.Rate3 END
Run Code Online (Sandbox Code Playgroud)

构建第二个表来保存这些数据而不是在需要时随时查询是否有意义?或者我应该坚持使用在请求时提取数据的运行时查询?

更重要的是,在确定是否应该在需要数据的任何时候运行查询,或者数据是否应该存储在它自己的单独表中时,要使用哪些因素?

HLG*_*GEM 9

接受的答案中没有涉及的一个问题是“随着时间的推移,您是否需要这个值”和“公式是否可能会改变”。

例如,考虑委托示例。如果已支付佣金,则应将金额存储为实际支付金额的历史数据。计算佣金的方式可能会在下个月发生变化(并且经常发生变化),但这不会改变必须单独存储的实际支付金额。

这与存储客户实际为产品支付的价格(在计算折扣等之后)是相同的想法,而不是依靠价格表的公式来做除初始计算之外的任何事情,因为下个月的产品价格可能不会与客户下订单时的价格相同。

如果您需要某个时间点的值的历史记录,请始终在使用初始计算公式后存储该值。


Con*_*lls 8

如果查询的运行频率相当低(例如报表),那么动态构建表可能更好1。如果查询频繁运行并且临时表是性能所必需的,那么您可能会遇到问题。

  • 如果该表的构建成本较低,则将其用作临时表。只要数据库足够快,您就可以逃脱。但是,您需要密切关注性能。

  • 如果表格不必完全更新,但会成为相对频繁的报告活动的主题,那么定期重建可能是最好的方法。

  • 如果表的构建成本很高但需要更新,您可能需要将其作为非规范化结构进行管理,作为索引视图或通过触发器进行维护。这相当复杂,并且给写操作带来了额外的负担。

    在更极端的情况下(即大数据量),您可能需要一种混合方法,即从针对性能优化的非规范化结构中查询历史数据,并从实时应用程序中查询当前数据。

    最极端的情况可以让您进入低延迟数据集市提要和混合 OLAP 解决方案,因此就兔子洞的深度而言,这是迄今为止最复杂的。除非您有真正的需求,否则最好避免使用。

在您上面描述的情况下,定期重建报告表听起来很合适。如果您需要在一天中间关闭以运行报告,那么您可以提供一个工具来强制从应用程序更新。否则,在通宵过程中运行它,代理可以看到他们的佣金“在前一个工作日的午夜”。

1 select into查询在 SQL Server 上创建临时表的速度非常快,因为插入操作的日志记录最少。

总而言之,您使用以下因素来确定是否应该为您的数据创建一个新表:

  • 多久需要一次数据
  • 获取数据的成本有多高
  • 数据需要更新到什么程度

  • @Rachel - 另外,“数据需要更新到什么程度?” (2认同)