【问题标题】:Create rails index to multi-column query with daterange使用日期范围为多列查询创建 Rails 索引
【发布时间】:2016-06-15 15:37:53
【问题描述】:

我在使用这两个查询时遇到了一些性能问题:

any_impression = Impression.exists?(user_id: user_id, created_at: range)
any_visit      = Visit.exists?(user_id: user_id, created_at: range)

他们为每个用户拥有大约 50 万条记录,并且运行时间超过 15 秒。

基于此,我想创建两个索引,每个搜索一个。

我的问题是,我应该创建的索引是:

add_index :visits, [:user_id, :created_at]
add_index :impressions, [:user_id, :created_at]

或者需要更多特定信息来查询上面使用创建的索引?

非常感谢。

【问题讨论】:

    标签: ruby-on-rails postgresql activerecord rails-activerecord postgresql-9.3


    【解决方案1】:

    那些索引应该没问题。在 Postgres 中,索引并不总是知道如何使用给定的运算符——它取决于索引类型。 This page from the manual 解释详情。

    您建议的索引将是 btree 索引。在我的实验中,告诉 ActiveRecord 根据范围查询时间戳列会产生BETWEEN ... AND ... SQL:

    User.where(created_at: (Date.parse('2015-01-01') ..
                            Date.parse('2016-01-01'))).to_sql
    

    给予:

    SELECT "users".*
    FROM   "users"
    WHERE  ("users"."created_at" BETWEEN '2015-01-01' AND '2016-01-01')
    

    这也是你看到的吗?然后 Postgres 应该使用你的索引,因为 BETWEEN 只是 <=>=

    您也可以使用EXPLAINEXPLAIN ANALYZE 手动运行查询,以查看索引是否按预期使用。

    【讨论】:

    • 感谢您的解释,链接非常有用。我创建了索引,查询现在在几毫秒内运行,令人难以置信而且非常高效,无论如何,再次感谢 =D。
    猜你喜欢
    • 2011-08-21
    • 2018-03-27
    • 1970-01-01
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    • 2012-09-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多