我有一个Firebird数据库,假设表A和B看起来像这样:
表A
TableB's Id | SomeNumber | OtherNumber | ComputedByField | OtherIntField
1 5 200 SomeNumber*OtherNumber 10
1 2 70 ... 20
表B
Id | Sum | Sum
1 Sum of OtherIntFIeld Sum of ComputedByField
where TableA'sId = TableB's Id
但是现在TableB正在填充(它是2k行),由于这个计算,访问它也变得很慢。
所以我的问题是:我应该删除TableA的computedby
字段并将其直接添加到TableB中,并且添加新的TableA行以手动修改对应的行吗? (这应该更快,但我真的不喜欢它)
编辑:性能问题来自这样一个事实:有两个computedby
字段在TableA上执行完全相同的查询但返回不同的字段。我想这是需要优化的部分。
Edit2:行计算如下
TABLEB_FIELD_X COMPUTED BY ((
select SUM(TableA.FieldX) from TableA
where TableA.FAT_ID = TableB.ID
))
TABLEB_FIELD_Y COMPUTED BY ((
select SUM(TableA.FieldY) from TableA
where TableA.FAT_ID = TableB.ID
))
我认为主要问题来自这两个独立字段从TableA查询相同行的事实,它们只是得到一个不同的字段。
答案 0 :(得分:1)
为什么不创建view,而不是TableB
? (警告:我从未使用过Firebird,我不知道它对视图的支持程度如何)。
这样的观点将是:
create view Totals (SumX, SumY)
as
select SUM(FieldX), SUM(FieldY)
from TableA
group by ID
每次更改TableA
时,此类视图(Totals
)都会自动更新。
一个不错的DBMS会在优化这个方面做得很好:只有在Totals
发生变化时才会重新计算{em> {/ 1>} TableA
,与TableB
不同,这将是Totals
每次都要重新计算(我假设您的性能问题 - 确定需要知道Firebird内部)。
select * from Totals where ID = ...
将像任何其他表一样(但是只读);您将使用以下内容过滤信息:
TableA
P.S。: Walter Mitty在下面的评论中提请我注意我对原始解决方案的假设,即{{1}}:
令人遗憾的是,基于SQL的DBMS 要求来自用户的此类物理设计细节具有良好的性能,这与DBMS应该擅长的相反(它具有所需的所有信息)自动完成工作,即物理数据结构和数据访问路径统计的所有权。)
答案 1 :(得分:0)
我会在表A上使用一个触发器,它在表A中的任何插入/更新/删除之后用字段的总和更新表B.
这会对表A上发生的任何事务产生一些额外的影响,但在查询表B时会更有效。
答案 2 :(得分:0)
不确定为什么每次更新时都要重新计算整个表格?这就是你的代码和解释似乎暗示的内容。
最好的办法是将计算值存储为常规值整数或结果。然后你还可以添加索引之类的东西。如果您将其保留为动态字段,则如果您有索引,则还必须动态重建索引。
标准程序是将其移至代码,并计算&更新其他两个中的任何一个时,动态更新ComputedValue字段。如果您在代码中有多个地方更新该字段,我会考虑优化您的代码。
此外,如果你真的需要加快速度,你可以使用存储过程(我不使用Firebird - 所以我不知道它是否支持它)并在需要时从你的代码中调用它们。 / p>