我有一個模型Activity,它有許多ActivitySecondaryUsers。我正試圖優化這個查詢:
2.6.3 :015 > /span> Activity. left_joins(:activity_secondary_users).where("activity_secondary_users.user_id = :id OR (primary_user_id = :id AND activity_type != '#{Activity::MENTION}')", id: 10000).order(created_at: :desc).limit(10).解釋
活動負載(812.7ms) SELECT"活動"。 * FROM "活動" LEFT OUTER JOIN "activity_secondary_users" ON "activity_secondary_users" 。 "activity_id" = "活動"。 "id" WHERE (activity_secondary_users. user_id = 10000 OR (primary_user_id = 10000 AND activity_type ! = '提')) ORDER BY "activity". "created_at" DESC LIMIT $1 [["limit", 10] ]
=>EXPLAIN for: SELECT "活動"。 * FROM "活動" LEFT OUTER JOIN "activity_secondary_users" ON "activity_secondary_users" 。 "activity_id" = "活動"。 "id" WHERE (activity_secondary_users. user_id = 10000 OR (primary_user_id = 10000 AND activity_type ! = '提')) ORDER BY "activity". "created_at" DESC LIMIT $1 [["limit", 10] ]
查詢計劃
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
限制(成本=1000.87.0.19659。 54 rows=10 寬度=138)(實際time=79. 769..737. 253 rows=10 loops= 1)
緩沖區:共享命中=2013672。
-> Gather Merge(cost=1000。 87..202514. 52 rows=108 寬度=138)(實際time=79. 768..737. 245 rows=10 loops= 1)
計劃中的工人。2)
啟動的工人。2
緩沖區:共享點擊=2013672
-> 嵌套回圈 left Join (cost=0. 84..201502. 03 rows=45 寬度=138)(實際time=36. 208..351. 256 rows=5 loops=3)
Filter: ((activity_secondary_users.user_id = 10000) OR ((activity.primary_user_id = 10000) and ((activity.activity_type)::text <> '提': :text))
Rows 移除by Filter: 181610
緩沖器:共享命中=2013672
-> 并行索引掃描使用 index_activities_on_created_at 對活動(cost=0。 42..28991. 70 rows=370715 width=138)(實際time=0。 027..52. 295 rows=181615 loops= 3)
緩沖區:共享命中=137766。
-> 索引掃描使用 index_activity_secondary_users_on_activity_id 對 activity_secondary_users (cost=0。 42..0. 45 rows=1 寬度=16)(實際time=0。 001..0. 001 rows=0 loops=544845)
索引條件。(activity_id = activities.id)
緩沖區:共享命中=1875906。
規劃時間。0.216 ms
執行 時間: 737.288 ms
索引:
- 活動: created_at, primary_user_id
- ActivitySecondaryUser: activity_id 。
我已經嘗試添加其他索引和改變排序屬性,但似乎沒有什么能讓它更快。該表有不到100萬條記錄,平均需要500毫秒以上。對于如何優化查詢有什么建議嗎?
uj5u.com熱心網友回復:
我會嘗試以降序添加第二個索引。 默認情況下,索引將是升序的,如果你有非常大的資料量,而且你經常想看到它的降序,可能值得擁有一個專用索引。
遷移將看起來像這樣:
def change
add_index(:activity, :created_at, order: {created_at: :desc})
結束。
關于它的Rails檔案在這里。https://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/add_index
那里有一個說明--如果你使用的是舊版本的MySQL,請注意
uj5u.com熱心網友回復: 看起來你要找的用戶,10000,已經不活躍了。 它不得不在所有的資料中走了一半,544845行活動,從最新的活動開始,然后才找到對該用戶的10次參考。
這可能是一個非常難以優化的查詢,因為 WHERE 的 ORed 分支在一個表中,但 ORDER BY 在另一個表中。
你是否可以檢測不活躍的用戶并拒絕為他們運行這種型別的查詢?
標籤:注意:MySQL只支持從8.0.1開始的索引順序(早期版本接受該語法但忽略它)。
