2

以下は、ユーザーの複数のアカウントによってグループ化された未表示メッセージ数のリストを返す実際の SQL クエリです。ただし、実際にはカウントは必要ありません。未表示のメッセージが存在することを示すために少しだけ必要です。かなり複雑な JOIN ロジックを分解せずに、COUNT を EXISTS/HAVING/DISCTINCT 1 やその他の手法に置き換えることで、クエリを最適化する方法がわかりますか?

最初は、簡単に最適化するために COUNT を FIRST に置き換えることさえできると思っていましたが、MySQL ではうまくいきません...

(私はこの質問を見てきましたが、GROUP BYにより、私が見た代替手段を適用することが難しくなります)

SELECT messages_to_user.account_id, COUNT(*) FROM

(SELECT 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 
    message_view.id as id, 
    message_view.message_id as message_id,
    message_view.user_id as user_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.id IS NULL

GROUP BY messages_to_user.account_id
4

3 に答える 3

1

カウントが必要ない場合は、最初の行のSELECTからCOUNT(*)を省略してください。

これによりクエリの実行が速くなるとは約束できませんが、この種の最適化に労力を費やす必要のある問題があるとは確信していません(「この種」とは「時期尚早」を意味すると思います")。

于 2012-08-10T16:34:29.940 に答える
0

SQL Serverでは、次のようにします。

case when exists(select * from messages where IsUnread = 1) then 1 else 0 as HasUnreadMessage

これは明らかに擬似コードです。おそらく、MySQLで機能させることができます。存在するチェックは、1つの行が見つかると停止する可能性があるため、はるかに安価であるはずです。

于 2012-08-10T16:34:03.030 に答える
0

結合されているサブクエリのサイズを縮小する方法は次のとおりです。

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
于 2012-08-10T16:57:00.247 に答える