【发布时间】:2021-10-18 01:23:54
【问题描述】:
我正在使用 MySQL。对于 MP 系统,我有两个表(+1 列出对话):
_ msg_individus (= members of a conversation)
mi_mcid : id of the conversation
mi_uid : id of the user
mi_ustatus : status of the conversation for the user (opened or closed)
mi_datelecture : the last time (timestamp) the user opened the conversation
现在我将mi_mcid 和mi_muid 索引为主键。
_ msg_messages (= messages of the conversation)
msg_id : id of the message
msg_uid : id of the user who wrote the message
msg_mcid : id of the conversation
msg_text : content of the message
msg_timestamp : when the message was posted
现在我将msg_id 作为主键,msg_mcid 作为索引。
事情是这样的:我想知道是否有用户未读的消息。为此,我比较了最后一个 msg_timestamp 和 mi_datelecture,如果第一个大于第二个,那么就有了新的东西。
但由于某种原因,此请求的性能非常糟糕,我无法弄清楚如何正确索引以及如何以最佳方式构建我的请求以提高性能。
这是我构建的:
SELECT 1 FROM msg_messages as msg
WHERE msg.msg_uid != :u_id
AND msg.msg_status = "1"
AND msg.msg_mcid IN (SELECT mi.mi_mcid
FROM msg_individus as mi
WHERE mi.mi_uid = :uid
AND mi.mi_ustatus = "2"
AND mi.mi_datelecture < msg.msg_timestamp)
LIMIT 0,1
例如,我尝试在msg_status、mi_uid、mi_status 上设置一些索引,但即使情况稍微好一点,性能也很难过哈哈。当我不比较 mi_datelecture 和 msg_timestamp 时,处理大约需要 0.05 秒,而我这样做需要 0.20 秒。
感谢您的建议。
(来自评论)新尝试:
SELECT 1
FROM msg_messages as msg
WHERE msg.msg_uid != :u_id
AND msg.msg_status = "1"
AND EXISTS
(
SELECT *
FROM msg_individus as mi
WHERE mi.mi_mcid = msg.msg_mcid
AND mi.mi_uid = :uid
AND mi.mi_ustatus = "2"
AND (mi.mi_datelecture = "0"
OR mi.mi_datelecture < msg.msg_timestamp)
)
LIMIT 0,1
【问题讨论】:
-
您正在查询
msg_timestamp。当然,很明显您应该在此基础上建立一个索引,但您似乎已经尝试了所有方法。 -
您是否正在查看一个用户可能参与的所有对话?如果是这样,您不需要对话列表吗?还是只是一个特定的对话?如果是这样,那么查询中的
msg_id在哪里? -
@TangentiallyPerpendicular 是的,我试过了^^
-
@RickJames 实际上我并不关心什么消息,甚至什么对话是新的,在这种情况下,我只是想知道用户是否有新消息
标签: mysql indexing query-optimization