我有两个表:conversations
和messages
,其中每个会话都有很多消息
Message: (id, conversation_id, text, inserted_at, ...)
Conversation: (id, user_id ...)
我想显示一个对话列表,对于每个对话,我想显示最近添加的消息的文本和时间戳。我还想根据最近添加的消息的时间戳(最新的消息)对这些对话进行排序
目前,我使用MAX函数计算这些(下面是我的ORM生成的查询)
SELECT c0."id", MAX(m5."inserted_at"),
(SELECT data->>'text' FROM messages
WHERE conversation_id = c0."id" AND type = 'message'
ORDER BY inserted_at DESC
LIMIT 1)
, c4."unread_count", v6."name", v6."id", (SELECT array(
SELECT type FROM tags
WHERE conversation_id = c0."id")) FROM "conversations" AS c0 INNER JOIN "tags" AS t1 ON t1."conversation_id" = c0."id" LEFT OUTER JOIN "messages" AS m2 ON m2."conversation_id" = c0."id" INNER JOIN "conversation_users" AS c7 ON c7."conversation_id" = c0."id" INNER JOIN "users" AS u3 ON c7."user_id" = u3."id" INNER JOIN "conversation_users" AS c4 ON c4."conversation_id" = c0."id" INNER JOIN "messages" AS m5 ON m5."conversation_id" = c0."id" INNER JOIN "visitors" AS v6 ON v6."id" = c0."visitor_id" WHERE (t1."type" = $1) AND (NOT (m2."visitor_id" IS NULL)) AND (u3."id" = $2) AND (c4."user_id" = $3) GROUP BY c0."id", c4."unread_count", v6."id", v6."name" ORDER BY MAX(m5."inserted_at") DESC LIMIT 10
我的问题是,每次添加新邮件时,将这些值反规范化并将它们直接保存在会话记录中会更有意义吗?
在has_many关联上执行3 MAX似乎非常昂贵(仅需3000条消息需要600毫秒)
答案 0 :(得分:0)
当然,是的,你必须这样做! 在对话表中添加新字段。你的规范化,但性能提升值得。
另一个选项,我不知道它是否符合您的要求,是将您的消息存储在对话表的xml或json字段中。当然,我认为除了从对话中选择消息之外你别做其他事情