优化mysql查询语句

时间:2013-05-15 08:34:10

标签: mysql optimization explain

我该如何优化此查询?

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使用位置
  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秒钟,并将我的慢查询日志文件转储为垃圾邮件。

感谢。

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分: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;