Mysql 如何改进此一对多ActiveRecord数据模型?

Mysql 如何改进此一对多ActiveRecord数据模型?,mysql,ruby-on-rails,activerecord,Mysql,Ruby On Rails,Activerecord,我有一个自主开发的(不是我自己的)版本控制系统,具有以下数据结构: create_table "activities", :force => true do |t| t.string "source" t.datetime "created_at", :null => false t.datetime "updated_at", :null => false t.integer "head_revision_id

我有一个自主开发的(不是我自己的)版本控制系统,具有以下数据结构:

  create_table "activities", :force => true do |t|
    t.string   "source"
    t.datetime "created_at",       :null => false
    t.datetime "updated_at",       :null => false
    t.integer  "head_revision_id"
  end

  add_index "activities", ["head_revision_id"], :name => "index_activities_on_head_revision_id"
  add_index "activities", ["source"], :name => "index_activities_on_source"

  create_table "activity_revisions", :force => true do |t|
    t.integer  "activity_id"
    t.string   "activity_type"
    t.string   "title"
    t.text     "content"
    t.text     "comment"
    t.integer  "modified_by_id"
    t.datetime "created_at",                      :null => false
    t.datetime "updated_at",                      :null => false
  end

  add_index "activity_revisions", ["activity_id"], :name => "index_activity_revisions_on_activity_id"
  add_index "activity_revisions", ["activity_type"], :name => "index_activity_revisions_on_activity_type"
  add_index "activity_revisions", ["title"], :name => "index_activity_revisions_on_title"
应用程序显示从最新到最旧、分页(will_paginate)20到页面的活动列表。这是用于生成列表的查询:

Activity.where(conditions)
        .joins(:head_revision)
        .includes(:head_revision)
        .order('activities.id DESC')
条件
根据从搜索表单传递的值而变化。对于初始列表显示,
条件
为空

从表面上看,这个查询非常简单,但在执行过程中,对于大型数据集来说,它的速度非常慢。我们目前有大约102000个活动记录和512000个活动修订记录。在我们的生产服务器上,查询需要将近2秒钟的时间来提供计数。在一个开发环境中,这是非常糟糕的

我觉得数据模型本身就有问题,我希望有人能给我一个更好的方法

编辑:解释无条件运行基本查询:

mysql> explain SELECT * FROM `activities`  INNER JOIN `activity_revisions` ON `activity_revisions`.`id` = `activities`.`head_revision_id`;
+----+-------------+--------------------+--------+--------------------------------------+---------+---------+--------------------------------------------+--------+-------+
| id | select_type | table              | type   | possible_keys                        | key     | key_len | ref                                        | rows   | Extra |
+----+-------------+--------------------+--------+--------------------------------------+---------+---------+--------------------------------------------+--------+-------+
|  1 | SIMPLE      | activities         | ALL    | index_activities_on_head_revision_id | NULL    | NULL    | NULL                                       | 106590 |       |
|  1 | SIMPLE      | activity_revisions | eq_ref | PRIMARY                              | PRIMARY | 4       | cms_production.activities.head_revision_id |      1 |       |
+----+-------------+--------------------+--------+--------------------------------------+---------+---------+--------------------------------------------+--------+-------+
2 rows in set (0.00 sec)
在count(*)查询中:


我看到你已经索引了好几列,这很好。我想说,确保查询尽可能高效的最佳方法之一是确保数据库中处理查询/检索的所有
条件
,都将相应的列编入索引

我看到您已经在为几个列编制索引,这很好。我想说,确保查询尽可能高效的最佳方法之一是确保数据库中处理查询/检索的所有
条件
,都将相应的列编入索引

猜测查询速度慢的原因一点也不有趣,幸运的是我们不必这么做

让我们看看您的
活动
查询实际上在做什么


听起来像是在查询一个mysql数据库,所以看一下解释结果的
键。正如MilesStanfield所建议的,听起来你会发现你没有有效地使用索引。

猜测查询速度慢的原因并不有趣,幸运的是我们不应该这样做

让我们看看您的
活动
查询实际上在做什么


听起来像是在查询一个mysql数据库,所以看一下解释结果的
键。正如MilesStanfield所建议的,听起来你会发现你没有有效地使用索引。

我在上面添加了几个解释。我在上面添加了几个解释。搜索会有点慢,因为大多数人都使用like。计数查询占用了大部分时间。搜索速度会有点慢,因为大多数人使用LIKE。更新:虽然我仍然觉得数据模型本质上是坏的,但我已经确定,实时和开发之间的时间差异很大的原因是由于percona的开发调优不当。设置innodb_buffer_pool_size=7GB大大提高了查询性能。更新:虽然我仍然觉得数据模型本身就不好,但我已经确定,实时和开发之间的时间差异很大的原因是由于percona开发调优不好。设置
innodb\u buffer\u pool\u size=7GB
大大提高了查询性能。
mysql> explain SELECT count(*) FROM `activities`  INNER JOIN `activity_revisions` ON `activity_revisions`.`id` = `activities`.`head_revision_id`;
+----+-------------+--------------------+--------+--------------------------------------+--------------------------------------+---------+--------------------------------------------+--------+-------------     +
| id | select_type | table              | type   | possible_keys                        | key                                  | key_len | ref                                        | rows   | Extra            |
+----+-------------+--------------------+--------+--------------------------------------+--------------------------------------+---------+--------------------------------------------+--------+-------------     +
|  1 | SIMPLE      | activities         | index  | index_activities_on_head_revision_id | index_activities_on_head_revision_id | 5       | NULL                                       | 106590 | Using index      |
|  1 | SIMPLE      | activity_revisions | eq_ref | PRIMARY                              | PRIMARY                              | 4       | cms_production.activities.head_revision_id |      1 | Using index      |
+----+-------------+--------------------+--------+--------------------------------------+--------------------------------------+---------+--------------------------------------------+--------+-------------     +
2 rows in set (0.00 sec)