3

有以下字段的“team_sector”表:id、team_id、sect_id、大小、级别

它包含每个“团队”实体的少量记录(用“team_id”字段引用)。每条记录代表球队体育场的扇区(共 8 个扇区)。

现在有必要实现一些搜索:

  • 按体育场总规模(SUM(size));
  • 最好的质量 (SUM(level)/COUNT(*))。

我可以创建这样的查询:

SELECT TS.team_id, SUM(TS.size) as OverallSize, SUM(TS.Level)/COUNT(TS.Id) AS QualityLevel
FROM team_sector
GROUP BY team_id
ORDER BY OverallSize DESC / ORDER BY QualityLevel DESC

但我在这里担心的是,每次执行查询时都会为每个团队进行计算。这不是太大的开销(至少现在),但我想避免以后出现性能问题。

我在这里看到 2 个选项。

第一个是在“团队”表中创建 2 个附加字段(例如)并在那里存储OverallSize 和 QualityLevel 字段。如果“扇区”表发生更改的信息 - 也更新这些表(使用触发器可能会很好,因为扇区表不会经常更改)。

第二个选项是创建一个提供所需数据的视图。

第二个选项对我来说似乎更容易,但我没有很多使用视图的经验/知识。

Q1:从您的角度来看,最好的选择是什么?为什么?也许您可以建议其他选择?

Q2:我可以创建视图以使其很少进行计算(至少每天一次)吗?如果是 - 如何?

Q3:为此目的使用触发器是否合理(第一种选择)。

使用 PS MySql 5.1,团队总数约为 1-2 千,扇区表中的记录总数 - 总共 6-8 千。我明白,这些数字非常小,但我想在这里实施最佳实践。

4

2 回答 2

2

我不会将计算字段添加到您的源表中。改为使用临时表,将源数据与计算数据分开。您可以使用由共享 PK 标识的一对一映射来通过减少索引等来提高性能(因此源行的 PK 等于计算表中行的 PK)。

好处是当您重建数据库时,很明显,由于缺少表,计算的数据已经过时。它还允许使用快捷方式,例如通过简单地删除临时表来清除所有计算数据,例如通过 cron 作业。以这种方式,计算的数据行还可以保留计算数据时的时间戳。以这种方式,如果最大缓存期限已过,则可以在加载时动态重新计算计算的数据,或者在服务器安静时在夜间作为批处理重新计算。

于 2011-01-02T19:37:14.183 回答
1

几(万)条记录无需担心。

最佳实践是

  • 以标准化方式存储数据并让数据库引擎处理计算
  • 正确索引您的数据,不时进行索引维护
  • 避免使用“父”记录存储聚合值
  • 在应用层做一些结果缓存以避免不必要的频繁访问数据库服务器
  • 当你得到它们时处理性能问题

是的,无论何时执行视图/查询,数据库都会计算SUM(),但我希望结果对于您描述的场景来说是非常即时的。

如果您遇到一个非常复杂的视图需要很长时间来计算并且您找不到任何进一步优化表的方法,您可以引入一个定期(或通过触发器)填充视图结果并查询的辅助表该表而不是慢视图。

恕我直言,预测可能的性能瓶颈并在它们实际出现之前“关闭”它们是在浪费你的时间。

于 2011-01-02T19:50:21.953 回答