【发布时间】:2012-08-09 17:33:13
【问题描述】:
我想知道为什么要这样做
UserView.where(:user_viewable_type => 'Song').order('created_at desc').limit(5)
运行需要 1213 毫秒。有点慢?
在 schema.rb 中 user_viewable_type 被索引:
add_index "user_views", ["user_viewable_type"], :name => "index_views_on_viewable_type"
即使在 psql 中:
"index_views_on_viewable_type" btree (user_viewable_type)
使用.explain 运行返回:
UserView.where(:user_viewable_type => 'Song').order('created_at desc').limit(5).explain
UserView Load (1801.4ms) SELECT "user_views".* FROM "user_views" WHERE "user_views"."user_viewable_type" = 'Song' ORDER BY created_at desc LIMIT 5
EXPLAIN (1.6ms) EXPLAIN SELECT "user_views".* FROM "user_views" WHERE "user_views"."user_viewable_type" = 'Song' ORDER BY created_at desc LIMIT 5
=> "EXPLAIN for: SELECT \"user_views\".* FROM \"user_views\" WHERE \"user_views\".\"user_viewable_type\" = 'Song' ORDER BY created_at desc LIMIT 5\n QUERY PLAN\n-------------------------------------------------------------------------------\n Limit (cost=17113.28..17113.28 rows=5 width=37)\n -> Sort (cost=17113.28..17147.82 rows=69085 width=37)\n Sort Key: created_at\n -> Seq Scan on user_views (cost=0.00..16883.78 rows=69085 width=37)\n Filter: ((user_viewable_type)::text = 'Song'::text)\n(5 rows)\n"
所以我决定分解查询并删除order,我得到:
UserView.where(:user_viewable_type => 'Song').limit(5).explain
UserView Load (1.6ms) SELECT "user_views".* FROM "user_views" WHERE "user_views"."user_viewable_type" = 'Song' LIMIT 5
order('created_at desc') 似乎导致查询变慢。但为什么?不能快点下单吗?
我在id 列上尝试了order:
UserView.where(:user_viewable_type => 'Song').order('id desc').limit(5).explain
UserView Load (44.8ms) SELECT "user_views".* FROM "user_views" WHERE "user_views"."user_viewable_type" = 'Song' ORDER BY id desc LIMIT 5
快多了!有什么问题?
我应该提几点:
- 如果您还没有注意到,这是一个多态表。
- 过去,我通过
t.rename :live_viewable_type, :user_viewable_type的Rails 迁移将:live_viewable_type重命名为:user_viewable_type。但是,我认为这应该不是问题,因为索引仍在右列。
【问题讨论】:
-
将问题中的“解释”替换为“解释分析”,并将其格式化为带有换行符的代码,以便于阅读。
标签: sql ruby-on-rails ruby-on-rails-3 postgresql