Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 通过查询优化组外计数(*)_Mysql_Sql_Count_Sql Optimization - Fatal编程技术网

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查询,它返回按用户的多个帐户分组的未查看邮件计数列表。然而,我们实际上并不需要计数,只是需要一点来表示存在未查看的消息。在不分离相当复杂的连接逻辑的情况下,您是否可以通过使用EXISTS/HAVING/DISCTINCT 1或其他技术替换COUNT来优化查询

我最初认为我甚至可以用FIRST来代替COUNT进行一些简单的优化,但MySQL不行

(我已经看过了,但是小组成员让我很难应用我见过的任何替代方案)


在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