因此 User
有许多 :orders
,这与您预期的一样。我还有一个 valid
订单范围,它应该通过确保订单处于一组白名单状态(例如,不是取消的订单)来过滤
我已经在订单表上声明了一些索引,我的 schema.rb
看起来像:
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"
当我运行 puts user.orders.valid.explain
时,我得到了这个:
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)
鉴于我正在搜索 user_id
和 state
,并且对这两个字段都有一个复合索引,为什么它不使用 index_orders_on_user_id_and_state
索引?或者我只是在读这个解释输出错误?
它是否进行两次传递?一个通过 user_id
查找订单,然后另一个通过检查 state
?
我需要经常对大量记录运行这样的查询。因此,任何保持速度的方法都是一件非常好的事情。
最佳答案
数据库系统可能决定不使用索引。比如Mysql,如果表数据很小,它可能会决定进行全表扫描。你可以尝试放入几百万条记录,然后再次执行查询,看看计划有何变化。
关于ruby - Rails 3 Postgres 使用单字段索引进行查询,难道不应该使用复合索引吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21034781/