2016-02-05 22 views
1

我有一個本土的(不是我自己的)版本具有以下數據結構系統:一個頁面我該如何改進這一個到許多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" 
    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') 

conditions根據從搜索形式傳遞的值而變化。對於初始列表顯示,conditions爲空。從表面上看,這個查詢很簡單,但在執行時,對於大型數據集來說,速度非常慢。我們目前有大約102,000條活動記錄和512,000條activity_revision記錄。在我們的生產服務器上,查詢需要將近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> 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) 
+0

更新:雖然我仍然覺得數據模型本身就不好,但我確定了現場和開發之間的大時序差異的原因是由於percona調整得不好。設置'innodb_buffer_pool_size = 7GB'可以大大提高查詢性能。 – Warren

回答

0

我看你已經索引數列這是很好的。我會說,確保查詢儘可能高效的最佳方法之一是確保處理db中查詢/檢索的所有conditions的索引的對應列。

+0

由於大多數人使用LIKE,因此搜索速度會有所緩慢。大部分時間都是COUNT查詢。 – Warren

0

猜猜爲什麼查詢速度慢沒有趣,幸運的是我們不應該這麼做。

看看http://guides.rubyonrails.org/active_record_querying.html#running-explain,讓我們看看你的Activity查詢實際上在做什麼。

這聽起來像你正在查詢一個MySQL數據庫,所以看看key在那些解釋結果。正如MilesStanfield所建議的,這聽起來就像你會看到你沒有有效地使用索引。

+0

我已經添加了幾個EXPLAIN的上面。 – Warren

相關問題