2016-09-26 222 views
0

日期范围查询似乎正在触及我的索引,但仍然很慢。表中约有30M行。我可以做什么来加快速度?优化日期范围查询

User.messages.where(message_type: 'incoming').where(created_at: start_date..end_date).explain 


Message Load (8322.3ms) SELECT "messages".* FROM "messages" WHERE "messages"."user_id" = $1 AND "messages"."message_type" = $2 AND ("messages"."created_at" BETWEEN '2016-09-23 00:00:00.000000' AND '2016-09-23 23:59:59.999999') [["user_id", 1], ["message_type", "incoming"]] 

QUERY PLAN 

Index Scan using index_messages_on_created_at on messages (cost=0.09..21223.80 rows=136690 width=527) 
     Index Cond: ((created_at >= '2016-09-23 00:00:00'::timestamp without time zone) AND (created_at <= '2016-09-23 23:59:59.999999'::timestamp without time zone)) 
     Filter: ((user_id = 1) AND ((message_type)::text = 'incoming'::text)) 
     (3 rows) 

回答

0

理想情况下,您应该有一个索引(user_id, message_type, created_at)。这将允许postgres通过仅使用该索引运行提供的查询。

+0

这似乎有助于缩小日期范围(单日),但在查询太多行时,在周/月日期范围内会被忽略。 – mnort9

+0

你在桌子上运行了'ANALYZE'吗?运行'ANALYZE“消息”;',然后再次运行查询。 – redneb

+0

同样的事情。对于某些用户查询的行数超过500K,表格只有30M行。它可能不够有选择性吗? – mnort9