【问题标题】:Understanding how to optimize a query via the Postgres/rails explain data了解如何通过 Postgres/rails 解释数据优化查询
【发布时间】:2013-01-20 19:47:59
【问题描述】:

我有以下疑问:

c = Invite.where(:invite_method => 'email', :email => email, :created_at => Time.zone.now.beginning_of_day..Time.zone.now.end_of_day).count

此查询需要一些时间,因为该表有 1m 多条记录。这是查询输出:

> invites_sent_today = Invite.where(:invite_method => 'email', :email => email, :created_at => Time.zone.now.beginning_of_day..Time.zone.now.end_of_day).exp 

Invite Load (62.3ms)  SELECT "invites".* FROM "invites" WHERE "invites"."invite_method" = 'email' AND "invites"."email" = 'santa@site.com' AND ("invites"."created_at" BETWEEN '2013-01-20 00:00:00.000000' AND '2013-01-20 23:59:59.999999')

EXPLAIN (2.2ms)  EXPLAIN SELECT "invites".* FROM "invites" WHERE "invites"."invite_method" = 'email' AND "invites"."email" = 'santa@site.com' AND ("invites"."created_at" BETWEEN '2013-01-20 00:00:00.000000' AND '2013-01-20 23:59:59.999999')

=> EXPLAIN for:

SELECT \"invites\".*
  FROM \"invites\"
 WHERE \"invites\".\"invite_method\" = 'email' 
   AND \"invites\".\"email\" = 'santa@site.com'
   AND (\"invites\".\"created_at\"
    BETWEEN '2013-01-2000:00:00.000000'                                                             
       AND'2013-01-20 23:59:59.999999'
      ;

QUERY PLAN\n------------------------------------------------------------------------------------------------------------------------------------------------------------------\n 
Index Scan using index_invites_on_created_at on invites  (cost=0.00..17998.11 rows=2 width=129)\n   
Index Cond: ((created_at >= '2013-01-20 00:00:00'::timestamp without time zone) AND (created_at <= '2013-01-20 23:59:59.999999'::timestamp without time zone))\n   
Filter: (((invite_method)::text = 'email'::text) AND ((email)::text = 'santa@site.com'::text))\n(3 rows)\n"

关于如何可能提高此查询性能的任何建议?谢谢

【问题讨论】:

  • 复合或部分索引可以加速这个特定的查询。
  • 示例:CREATE INDEX zzzzz ON invites (email) WHERE invite_method = 'email' BTW:检查查询计划的方法是运行EXPLAIN ANALYZE query statement,并查看观察到的和预期的差异。
  • 您是否总是查询过去 24 小时?是的 -> 创建额外的表并在一天结束时截断它,查询会非常快。如果电子邮件上的基数更好,请在电子邮件上创建索引
  • @iddqd 也许最后一天的部分索引会更好?并在一天结束时重新创建索引。
  • @AnApprentice 如果您想要对最后一天(或 3 天或...)的数据进行部分索引,则必须重新创建索引,因为“最后一天”这一天会不断变化。如果你想要像 "invite_method" = 'email' 这样的部分索引 - 你不需要重新创建它。

标签: ruby-on-rails postgresql postgresql-9.1


【解决方案1】:

按照 Igor 的建议,尝试使用复合索引:

CREATE INDEX index_invites_email_created_at on invites(email,created_at);

【讨论】:

    猜你喜欢
    • 2021-11-21
    • 1970-01-01
    • 2023-03-19
    • 2013-10-11
    • 2015-01-19
    • 1970-01-01
    • 1970-01-01
    • 2021-11-16
    • 1970-01-01
    相关资源
    最近更新 更多