【发布时间】:2019-10-04 05:27:28
【问题描述】:
我正在尝试获取属于用户所有对话的所有标签(用户通过ConversationUserPair 加入进行了许多对话) - 但查询平均需要 2,000 毫秒。
SELECT "tags"."tag_text_downcased"
FROM "tags"
INNER JOIN "conversations" ON "tags"."conversation_id" = "conversations"."id"
INNER JOIN "conversation_user_pairs" ON "conversations"."id" = "conversation_user_pairs"."conversation_id"
WHERE "conversation_user_pairs"."user_id" = ?
AND "conversation_user_pairs"."conversation_status" = ?
AND ("tags"."user_id" = ?);
当我在 psql 控制台中运行 EXPLAIN ANALYZE 时,得到的响应是:
EXPLAIN ANALYZE
SELECT "tags"."tag_text_downcased" FROM "tags" INNER JOIN "conversations" ON "tags"."conversation_id" = "conversations"."id" INNER JOIN "conversation_user_pairs" ON "conversations"."id" = "conversation_user_pairs"."conversation_id" WHERE "conversation_user_pairs"."user_id" = '459' AND "conversation_user_pairs"."conversation_status" = 'active' AND ("tags"."user_id" = '459');
Nested Loop (cost=462.87..486.65 rows=1 width=11) (actual time=0.457..1.886 rows=40 loops=1)
Join Filter: (tags.conversation_id = conversations.id)
-> Merge Join (cost=462.78..482.97 rows=1 width=19) (actual time=0.401..1.334 rows=40 loops=1)
Merge Cond: (tags.conversation_id = conversation_user_pairs.conversation_id)
-> Sort (cost=462.70..462.83 rows=259 width=15) (actual time=0.332..0.337 rows=40 loops=1)
Sort Key: tags.conversation_id
Sort Method: quicksort Memory: 27kB
-> Bitmap Heap Scan on tags (cost=4.49..460.62 rows=259 width=15) (actual time=0.152..0.295 rows=40 loops=1)
Recheck Cond: (user_id = 459)
Heap Blocks: exact=23
-> Bitmap Index Scan on index_tags_on_user_id_and_conversation_id (cost=0.00..4.47 rows=259 width=0) (actual time=0.105..0.105 rows=40 loops=1)
Index Cond: (user_id = 459)
-> Index Only Scan using by_user_and_conversation_and_status on conversation_user_pairs (cost=0.08..20.02 rows=522 width=4) (actual time=0.066..0.956 rows=390 loops=1)
Index Cond: ((user_id = 459) AND (conversation_status = 'active'::text))
Heap Fetches: 134
-> Index Only Scan using index_conversations_on_id on conversations (cost=0.08..3.68 rows=1 width=4) (actual time=0.013..0.013 rows=1 loops=40)
Index Cond: (id = conversation_user_pairs.conversation_id)
Heap Fetches: 40
我认为我在有问题的三个单独的表上有适当的索引。我有:
add_index "tags", ["conversation_id", "user_id", "tag_text_downcased"], name: "find_tag_text_downcased_tags"
add_index "tags", ["conversation_id", "user_id"], name: "index_conversation_first_tags"
add_index "tags", ["user_id", "conversation_id"], name: "index_tags_on_user_id_and_conversation_id"
add_index "conversation_user_pairs", ["user_id", "conversation_id", "conversation_status"], name: "by_user_and_conversation_and_status"
add_index "conversations", ["id"], name: "index_conversations_on_id"
这里没有什么可做的来加快查询速度,因为它看起来像是在使用每个表的索引?或者有没有办法拥有一个多表索引?
【问题讨论】:
-
您的
EXPLAIN以毫秒为单位显示时间,而不是秒。该查询的执行时间不到 2 毫秒。最慢的部分是在conversation_user_pairs上仅扫描索引,大约需要 1 毫秒,可能是因为 134 次堆提取(表数据):explain.depesz.com/s/7DYn -
@Ancoron 感谢您的链接,非常有帮助。是的,这个特定的查询运行得很快,但我的服务器工具显示这个查询有时会花费超过 4,000 毫秒。
标签: sql postgresql activerecord indexing postgresql-performance