1

我有这两个查询的一些性能问题创建轨道指数多列查询:与日期范围

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] 

还是需要更多的一些具体信息,以上述使用的查询索引创建的?

非常感谢。

回答

1

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

您提出的索引应该是btree索引。在我的实验,告诉ActiveRecord的查询基于一系列timestamp列产生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手动运行查询,查看索引是否按照您的预期使用。

+0

感谢您的解释和链接是非常有用的。我创建索引,查询现在几毫秒内运行,令人难以置信,非常高效,无论如何,再次感谢= D。 – overallduka