如何通过大型数据集提高效率(至少我认为它们很大)?

时间:2016-04-14 02:01:19

标签: database-design

我有一个数据库,它建模的数据类似于您可能看到的为体育收集的数据类型。我在这些活动中有用户事件用户拥有角色。这些事件中的每一个还具有 stats 并且属于类别,这些都是当前相关的:

=========  ========== ============
| users |  | events | | category |
|=======|  |========| |==========|
| id    |  | id     | | id       |
---------  ---------- ------------

=========================    =======================
| roles                 |    | stats               |
|=======================|    |=====================|
| id                    |    |id                   |
| user_id -> users.id   |    | role_id -> roles.id |
| event_id -> events.id |    -----------------------
| category_id -> cat... |
-------------------------

我一直在努力保持一切都很好地分离和规范化,但我开始看到一个重要的效率权衡。数据是分批添加的,粗略估计每个事件有大量的 stats ,我一次吸引了数百个事件。目前我只玩一个用户并拥有170,000个统计数据,这可能是此用户的四分之一* 统计

以下是我如何查询此内容的示例:

SELECT avg(some_data) FROM stats
    JOIN roles ON stats.role_id = roles.id
    JOIN users ON roles.user_id = roles.id
    JOIN events ON roles.event_id = events.id
    JOIN categories ON roles.category_id = categories.id
        WHERE users.u_thing = 'something'
            AND categories.name = 'something'
    GROUP BY stats.timestamp 

此查询(在授予的虚拟主机上)平均花费8秒,并且正在执行超过14000行的avg()

我对数据库架构或设计并不是特别熟悉,所以我不知道我能在这里做些什么来优化我的架构/访问模式。

Addtional

  • 缓存结果在这里是有限的实用程序,因为可以经常添加新事件。
  • 由于与之前相同的原因,存储预先计算的统计信息很困难。
  • 我已将所有相应的列编入索引(非常肯定)。
  • 我考虑过将这些支点组合到 stats 表中,但如果有更好的方法,我会更开放。

1 个答案:

答案 0 :(得分:1)

对于类JOIN操作,从多个表中查询或过滤等常规技术效率很低。由于数据库必须提取满足第一个where子句的所有角色,然后如果它们在表“users”中并且满足第二个where子句“roles.user_id = roles.id”作为示例,则逐个检查它们列表。

相反,最有效的方法是从所有基础表构建物化视图。您将认为物化视图是一种冗余数据结构,旨在加速复杂的JOIN查询。

JOIN via materialized view帖子详细阐述了这一主题。