【问题标题】:Optimize mysql query statement优化mysql查询语句
【发布时间】:2013-05-09 17:54:05
【问题描述】:

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

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 秒,并将我的慢查询日志文件转储满垃圾。

谢谢。

【问题讨论】:

    标签: mysql optimization explain


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      尝试使用以下查询在 (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-09-04
        • 1970-01-01
        • 2021-11-22
        • 2012-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-31
        • 2011-01-22
        相关资源
        最近更新 更多