我目前运行一个网站,该网站在列表中跟踪最新的分数和评级。该列表有数千个经常更新的条目,并且该列表应该可以按这些分数和评级列进行排序。
我获取此数据的 SQL 目前看起来像(大致):
SELECT e.*, SUM(sa.amount) AS score, AVG(ra.rating) AS rating
FROM entries e
LEFT JOIN score_adjustments sa ON sa.entry_id = e.id
HAVING sa.created BETWEEN ... AND ...
LEFT JOIN rating_adjustments ra ON ra.entry_id = e.id
HAVING ra.rating > 0
ORDER BY score
LIMIT 0, 10
表格在哪里(简化):
entries:
id: INT(11) PRIMARY
...other data...
score_adjustments:
id: INT(11), PRIMARY
entry_id: INT(11), INDEX, FOREIGN KEY (entries.id)
created: DATETIME
amount: INT(4)
rating_adjustments:
id: INT(11), PRIMARY
entry_id: INT(11), INDEX, FOREIGN KEY (entries.id)
rating: DOUBLE
大约有 300,000score_adjustments
个条目,并且它们以每天大约 5,000 个的速度增长。大约是那个的rating_adjustments
1/4。
现在,我不是 DBA 专家,但我猜打电话SUM()
总是AVG()
不是一件好事——尤其是当sa
包含ra
数十万条记录时——对吧?
我已经对查询进行了缓存,但我希望查询本身快速 - 但仍尽可能保持最新。我想知道是否有人可以分享任何解决方案来优化像这样的繁重的连接/聚合查询?如有必要,我愿意进行结构性改变。
编辑 1
添加了有关查询的更多信息。