有关预先计算的SQL属性的指导

时间:2010-02-05 21:33:11

标签: sql precompute

我经常处理具有从其成员或子成员派生的属性的聚合或父实体。例如:

  • byte_count对象的packet_countTcpConnection来自。{ 它的两个成分TcpStream对象的相同属性,反过来也是如此 从其成分TcpPacket对象计算。

  • Invoices对象可能有一个total,它基本上是它的SUM() 成分InvoiceLineItems'价格,有一点运费,折扣和税 投入的逻辑。

当处理数百万个数据包或数百万个已开发票的订单项时(我希望!),这些派生属性的按需计算 - 无论是在VIEW中还是更常见于报表或Web界面等表示逻辑中 - 通常都是如此无法接受的慢。

在性能问题强迫您的手之前,您如何决定是否将派生属性“推广”到预先计算的字段?

3 个答案:

答案 0 :(得分:3)

我个人不会非正规化,直到性能权衡迫使我的手(因为非规范化的缺点太过激烈恕我直言),但你也可以考虑:

  1. 便利性:例如如果两个不同的客户端应用程序想要计算相同的派生属性,则它们都必须对查询进行编码以计算它们。非规范化以更简单的方式为客户端应用程序提供派生属性。
  2. 长期稳定性:例如如果用于计算派生属性的公式是可更改的,则非规范化允许您在某个时间点捕获并存储派生值,以便将来的计算永远不会出错
  3. 更简单的查询:增加数据库结构的复杂性可能意味着您的选择查询在客户端更简单。
  4. 效果:对非规范化数据的选择查询可以更快。
  5. 参考:The Database Programmer: The Argument for Denormalization。一定要阅读他关于保持非规范化值正确的文章 - 他的建议是使用触发器。这带来了一种权衡非规范化所需要的。

答案 1 :(得分:1)

基本上,你没有。你留下了性能问题迫使你的手。

这是最好的答案,因为99%的时间, 要像这样进行预优化,最好立即计算它。

然而,对于客户端应用程序开发人员而言,出现错误的先入之见是很常见的,例如“按需计算...派生属性......”经常< / strong>不可接受的慢“,这不是真的。这里正确的措辞是“ 很少不可接受的慢”。

因此,除非您是这方面的专家(数据库开发架构师等),否则您不应该进行过早优化。等到明显的必须修复然后查看预聚合。

答案 2 :(得分:0)

数据当前必须如何确定实现方式。

我将假设两个简单的状态:当前或非当前。

  • 当前:索引视图,触发器,存储过程以维护聚合表等
  • 不是最新的:报告服务快照,日志传送/复制,数据仓库等

那就是说,我会针对与prod中相同数量的数据进行开发,因此我对响应时间有一定的信心。您应该很少对代码性能感到惊讶......