Mysql 通过查询优化组外计数(*)
下面是一个正在工作的SQL查询,它返回按用户的多个帐户分组的未查看邮件计数列表。然而,我们实际上并不需要计数,只是需要一点来表示存在未查看的消息。在不分离相当复杂的连接逻辑的情况下,您是否可以通过使用EXISTS/HAVING/DISCTINCT 1或其他技术替换COUNT来优化查询 我最初认为我甚至可以用FIRST来代替COUNT进行一些简单的优化,但MySQL不行 (我已经看过了,但是小组成员让我很难应用我见过的任何替代方案)Mysql 通过查询优化组外计数(*),mysql,sql,count,sql-optimization,Mysql,Sql,Count,Sql Optimization,下面是一个正在工作的SQL查询,它返回按用户的多个帐户分组的未查看邮件计数列表。然而,我们实际上并不需要计数,只是需要一点来表示存在未查看的消息。在不分离相当复杂的连接逻辑的情况下,您是否可以通过使用EXISTS/HAVING/DISCTINCT 1或其他技术替换COUNT来优化查询 我最初认为我甚至可以用FIRST来代替COUNT进行一些简单的优化,但MySQL不行 (我已经看过了,但是小组成员让我很难应用我见过的任何替代方案) 在SQL Server中,我将执行以下操作: case when
在SQL Server中,我将执行以下操作:
case when exists(select * from messages where IsUnread = 1) then 1 else 0 as HasUnreadMessage
这显然是伪代码。也许你可以让它为MySQL工作。exists检查应该便宜得多,因为它可以在找到一行时停止。如果不需要计数,只需在第一行的SELECT中忽略计数(*)
我不能保证这将使您的查询运行得更快,但我也不相信您有任何问题需要花费精力进行此类优化(我认为“此类”的意思是“过早”)。如何减少正在连接的子查询的大小:
SELECT DISTINCT messages_to_user.account_id FROM
(SELECT DISTINCT message.id as id, root_message.account_id as account_id
FROM message
JOIN message as root_message
on message.conversation_id = root_message.id
AND (root_message.created_by = {user_id}
OR root_message.to_user_id = {user_id}
OR root_message.to_user_id IS NULL)
AND message.created_by != {user_id}
) messages_to_user
LEFT JOIN
(SELECT DISTINCT message_id
FROM message_view
WHERE message_view.user_id = {user_id}) viewed_messages
ON messages_to_user.id = viewed_messages.message_id
WHERE viewed_messages.message_id IS NULL
过早优化警告已经成为性能问题的标准答案。您如何确定存在未读消息?只需删除计数而不替换就可以删除该信息,不是吗?usr-不,它仍然有效-左连接。。。如果NULL在MYQSL中起到了“除外”的作用,那么我会得到一个设置,它会排除任何已查看的消息。请让我澄清:您的左连接已被过滤到消息\u到\u用户中与已查看\u消息中的任何内容都不匹配的项,因此我不知道如何减少确认不匹配的工作量。随后,您通过合并属于同一个messages_to_user.account_id的messages_to_user.id的多个值来修剪您的结果,但这与您的左加入的费用几乎没有关系。Narveson-您完全正确-正在取笑我错过了明显的结果
SELECT DISTINCT messages_to_user.account_id FROM
(SELECT DISTINCT message.id as id, root_message.account_id as account_id
FROM message
JOIN message as root_message
on message.conversation_id = root_message.id
AND (root_message.created_by = {user_id}
OR root_message.to_user_id = {user_id}
OR root_message.to_user_id IS NULL)
AND message.created_by != {user_id}
) messages_to_user
LEFT JOIN
(SELECT DISTINCT message_id
FROM message_view
WHERE message_view.user_id = {user_id}) viewed_messages
ON messages_to_user.id = viewed_messages.message_id
WHERE viewed_messages.message_id IS NULL