Reputation: 1549
I am having some performance problems with this two queries:
any_impression = Impression.exists?(user_id: user_id, created_at: range)
any_visit = Visit.exists?(user_id: user_id, created_at: range)
They have about 500k of records for each user and are taking more than 15s to run.
Based on this I would like to create two indexes, one for each search.
My question is, the indexes I should create are:
add_index :visits, [:user_id, :created_at]
add_index :impressions, [:user_id, :created_at]
Or need more some specific information to queries above use the indexes created ?
Thanks much.
Upvotes: 1
Views: 550
Reputation: 24551
Those indexes should be fine. In Postgres an index doesn't always know how to use a given operator---it depends on the index type. This page from the manual explains the details.
Your proposed indexes would be btree indexes. In my experiments, telling ActiveRecord to query a timestamp column based on a range produces BETWEEN ... AND ...
SQL:
User.where(created_at: (Date.parse('2015-01-01') ..
Date.parse('2016-01-01'))).to_sql
gives:
SELECT "users".*
FROM "users"
WHERE ("users"."created_at" BETWEEN '2015-01-01' AND '2016-01-01')
Is that what you're seeing also? Then Postgres should use your index, because BETWEEN
is just <=
and >=
.
You could also run the query by hand with EXPLAIN
or EXPLAIN ANALYZE
to see if the index is used as you expect.
Upvotes: 1