【发布时间】:2011-12-30 01:05:00
【问题描述】:
我有一个棒球工具,可以让用户分析球员的历史击球数据。例如,在过去 7 天的夜间条件下,A-Rod 有多少次点击?我想扩大时间范围,以便用户可以分析球员的击球统计数据,最早可以追溯到 365 天。但是,这样做需要进行一些严格的性能优化。这是我目前的模型集:
class AtBat < ActiveRecord::Base
belongs_to :batter
belongs_to :pitcher
belongs_to :weather_condition
### DATA MODEL ###
# id
# batter_id
# pitcher_id
# weather_condition_id
# hit (boolean)
##################
end
class BattingStat < ActiveRecord::Base
belongs_to :batter
belongs_to :recordable, :polymorphic => true # e.g., Batter, Pitcher, WeatherCondition
### DATA MODEL ###
# id
# batter_id
# recordable_id
# recordable_type
# hits7
# outs7
# at_bats7
# batting_avg7
# ...
# hits365
# outs365
# at_bats365
# batting_avg365
##################
end
class Batter < ActiveRecord::Base
has_many :batting_stats, :as => :recordable, :dependent => :destroy
has_many :at_bats, :dependent => :destroy
end
class Pitcher < ActiveRecord::Base
has_many :batting_stats, :as => :recordable, :dependent => :destroy
has_many :at_bats, :dependent => :destroy
end
class WeatherCondition < ActiveRecord::Base
has_many :batting_stats, :as => :recordable, :dependent => :destroy
has_many :at_bats, :dependent => :destroy
end
为了使我的问题保持合理的长度,让我叙述一下我正在做什么来更新 batting_stats 表,而不是复制一堆代码。让我们从 7 天开始。
- 检索过去 7 天的所有 at_bat 记录。
- 遍历每个 at_bat 记录...
- 给定一个at_bat记录,获取关联的batter和关联weather_condition,找到正确的batting_stat记录(BattingStat.find_or_create_by_batter_and_recordable(batter, weather_condition),然后更新batting_stat记录。
- 对击球手和投手重复第 3 步(可记录)。
其他时间段也会重复步骤 1-4 - 15 天、30 天等。
现在我可以想象,如果我要将时间段从可控制的 7/15/30 扩展到 7/15/30/45/60/90/,那么每天运行一个脚本来进行这些更新将是多么费力。 180/365。
所以我的问题是,您将如何让它以最高性能运行?
【问题讨论】:
-
我为高尔夫应用构建了一个类似的系统。我愿意分享,但这需要相当广泛的解释。您是否愿意改变您的架构,或者您只是在寻找一种方法来优化您现有的架构?
-
很高兴听到您是如何做到的。愿意更新拱门,但可能会在路上。
-
您要处理多少条记录?肯定不会有那么多棒球数据点(数十万?)。你不能把这块地块保存在内存中,如果需要的话,可能会被玩家分割成一张地图,然后即时计算?
-
我不确定您是否可以将其移植到 MySQL,但对于 PostgreSQL,您会执行类似tech.jonathangardner.net/wiki/PostgreSQL/Materialized_Views 的操作(您绝对应该尝试直接使用数据库,因此请考虑在 @ 上提问987654322@)
标签: mysql ruby-on-rails ruby performance optimization