我有以下SQL方案:
create table dbo.Baskets (
Id int not null primary key clustered (Id),
Name nvarchar (80) not null
)
create table dbo.Products (
Id int not null primary key clustered (Id),
BasketId int not null,
Price decimal (10, 2) not null,
Name nvarchar (80) not null
)
所以一个篮子可以有很多产品。
我经常需要找到特定价格区间的篮子。
我知道篮子价格是其产品价格的总和。
问题
我应该使用TotalPrice向Baskets添加一列吗?
这会大大提高查询效果吗?
产品更新后可以自动完成吗?
我应该在这里索引一些列吗?
答案 0 :(得分:1)
个人意见,我可能真的对此感到非常讨厌,但这听起来像是过早优化的明显例子。
计算篮子总成本是否需要JOIN
瓶颈?
如果没有,你在这里花费的任何努力而不是优化实际的瓶颈都是不合理的。如果它占整个过程的1%,但是你加快了100%,那么你的过程将快1%。
另一方面,如果您发现该过程的其他部分占用了90%的时间并且加快了10%,那么您的流程速度提高了9%。
如果JOIN
是瓶颈,或者至少足够慢以至于影响用户体验,那么你必须权衡利弊。
对我而言,这个骗局相当大。根据经验,在大多数现实生活中,数据库中的重复信息会导致错误 - 将成为一些重构,无法预料/未经测试的边缘情况,疲惫的同事修复另一个问题, ....会导致您的制作服务不能正确更新购物篮的总价,并且您将向最终用户显示不正确的信息。
你只需要决定一个罕见的不正确的总篮价(可能永远不会,很可能很少但仍然会发生)是否可以接受性能提升。
如果您尚未量化性能提升,我们为什么要进行此讨论?你正在谈论重复数据库信息(一个坏事),因为它可能带来未知的,可能是空的好处。
答案 1 :(得分:0)
INNER JOIN
和聚合。如果您经常在UI中列出订单,则可以显示总计而无需重新计算。早期阶段的最佳解决方案是通过使用总金额和其他汇总字段可用的订单视图来将您的实施与应用程序隔离。一旦遇到性能问题,就可以添加计算字段而不会影响代码。
如果数据库允许窗口函数计算总计为:
SUM(amount) OVER (PARTITION BY OrderID) AS TotalAmount
答案 2 :(得分:0)
一如既往......一切都取决于。
添加计算列的优点(TotalPrice) 无需每次都重新计算,特别是在基于totalPrice进行检索时(更少的CPU时间,但更多的磁盘空间和检索工作)
缺点 如果另一个字段发生变化(例如一个项目的价格),则引入错误的可能性。或者如果您决定添加其他列,例如数量或折扣。
确定哪种方法正确的最佳方法是测试。一种方法是规范化所有内容,即没有总价格,并采用指标,然后在一段时间后将totla价格作为优化添加,并采取进一步的指标,看看是否有改进。
与索引相同,尽管您正在搜索的列应该被编入索引。
希望这有帮助