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)