【问题标题】:Why is this query running slow?为什么此查询运行缓慢?
【发布时间】: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

快多了!有什么问题?

我应该提几点:

  1. 如果您还没有注意到,这是一个多态表。
  2. 过去,我通过t.rename :live_viewable_type, :user_viewable_type 的Rails 迁移将:live_viewable_type 重命名为:user_viewable_type。但是,我认为这应该不是问题,因为索引仍在右列。

【问题讨论】:

  • 将问题中的“解释”替换为“解释分析”,并将其格式化为带有换行符的代码,以便于阅读。

标签: sql ruby-on-rails ruby-on-rails-3 postgresql


【解决方案1】:

据我所知,问题可能是:

a) 你没有被created_at索引

或:

b) 数据库正在选择一个索引或另一个(即使用created_at 索引,使user_viewable_type 规范变慢,反之亦然)。

如果您经常拨打这些电话,则可能值得在 [created_at, user_viewable_type] 上查看组合索引(或其他方式:[user_viewable_type, created_at],具体取决于哪个会更快地缩小您的结果范围)。

【讨论】:

  • 我刚刚读过的一篇类似文章,解释了你的建议:tomafro.net/2009/08/…
  • 对,他写的和我想的差不多。如果您对[created_at, user_viewable_type] 进行索引,您的结果会更好吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
  • 2019-01-28
  • 2016-03-27
  • 1970-01-01
  • 1970-01-01
  • 2021-11-04
相关资源
最近更新 更多