So User has many :orders, which works like you expect. I also have a valid scope on order that should filter by ensuring the orders are in a set of whitelisted states (not canceled orders, for instance)
I've declared some indices on the orders table, and my schema.rb looks like:
add_index "orders", ["state"], :name => "index_orders_on_state"
add_index "orders", ["user_id", "state"], :name => "index_orders_on_user_id_and_state"
add_index "orders", ["user_id"], :name => "index_orders_on_user_id"
When I run puts user.orders.valid.explain I get this:
EXPLAIN for: SELECT "orders".* FROM "orders"
WHERE "orders"."user_id" = 1 AND
"orders"."state" IN ('pending', 'packed', 'shipped', 'in_transit', 'delivered', 'return_pending', 'returned')
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on orders (cost=4.60..154.88 rows=40 width=3323)
Recheck Cond: (user_id = 1)
Filter: ((state)::text = ANY ('{pending,packed,shipped,in_transit,delivered,return_pending,returned}'::text[]))
-> Bitmap Index Scan on index_orders_on_user_id (cost=0.00..4.59 rows=44 width=0)
Index Cond: (user_id = 1)
So given that I am searching on user_id and state, and a have a compound index for both those fields, why is it not using the index_orders_on_user_id_and_state index? Or am I just reading this explain output wrong?
Is it doing two passes? One to find orders by user_id, and then another pass to check for state?
I need to run queries like this a lot, on a lot of records at once. So any way to keep it speedy is a very good thing.
statevalues? Sometimes the table stats suggest that a scan will be cheaper than using an index. Indexes give the query optimizer extra options, they don't force the optimizer to make any particular choices.statecan be one of 8 or 9 values, so perhaps it's just deciding that it doesn't need the more specific index. I guess the choice to use an index or not is more nuanced than I thought it to be.stateof'pending', ...'returned'(i.e. the ones you're looking for) then consulting the index might be pointless. Query optimization is a bit of a black art, it depends on the queries, the indexes, and the contents of the table. Also, indexing low cardinality columns generally isn't that useful and youstatemight fall in the low cardinality category.