0

我应该如何优化这个查询?

EXPLAIN EXTENDED SELECT 
    cm . *,
    u1.Firstname AS u1Firstname,
    u1.Lastname AS u1Lastname,
    u2.Firstname AS u2Firstname,
    u2.Lastname AS u2Lastname,
    COUNT(*) AS Count
FROM
    ChatMessage AS cm
        LEFT JOIN
    Users AS u1 ON cm.UserId = u1.UserId
        LEFT JOIN
    Users AS u2 ON cm.FriendId = u2.UserId
WHERE
    (cm.UserId IN (292 , 289)) AND (cm.FriendId IN (292 , 289))
ORDER BY cm.DateAdded DESC;

解释:

1 SIMPLE cm ALL fk_ChatMessage_Users1,fk_ChatMessage_Users2 238 59.24 使用 where
1 SIMPLE u1 eq_ref PRIMARY PRIMARY 4 mhware.cm.UserId 1 100.00
1 SIMPLE u2 eq_ref PRIMARY PRIMARY 4 mhware.cm.FriendId 1 100.00

问题是:ChatMessage 正在使用外键,一个在 UserId 上,一个在 FriendId 上,指向用户表中的 UserId。

在 EXPLAIN 上,您可以看到它不知道如何正确使用索引。如果我添加(UserId,FriendId)或/和(FriendId,UserId)的新索引,它有4种可能性并且不使用其中任何一种。

该语句运行大约 1 秒,并且将我的慢查询日志文件转储为充满垃圾。

谢谢。

4

2 回答 2

0

您可以尝试添加 2 个索引吗?一个在 cm.UserID 上,另一个在 cm.FriendId 上?我不太了解您的外键设置,因为您使用的是左连接,所以您说用户可能不存在?为什么要使用外键?

于 2013-05-15T14:17:16.627 回答
0

尝试使用以下查询在 (UserId, FriendId) 上添加新索引:

SELECT 
    cm . *,
    u1.Firstname AS u1Firstname,
    u1.Lastname AS u1Lastname,
    u2.Firstname AS u2Firstname,
    u2.Lastname AS u2Lastname,
    COUNT(*) AS Count
FROM (select 289 u, 289 f union all 
      select 289, 292 union all 
      select 292, 289 union all 
      select 292, 292) uf
JOIN ChatMessage AS cm ON uf.u = cm.UserId and uf.f = cm.FriendId
LEFT JOIN Users AS u1 ON cm.UserId = u1.UserId
LEFT JOIN Users AS u2 ON cm.FriendId = u2.UserId
ORDER BY cm.DateAdded DESC;
于 2013-05-15T14:27:50.307 回答