从这个查询的MySQL索引中受益?

时间:2011-03-08 11:00:21

标签: mysql indexing

更新:添加了最常运行的查询:

(在考虑索引时可能需要???)

SELECT m.time, m.message, m.receiver_uid AS receiver, m.sender_uid AS sender
    FROM messages AS m, users AS u
    WHERE u.uid = '$coID' 
        AND ( (m.receiver_uid = '$meID' AND m.sender_uid = '$coID') OR
              (m.receiver_uid = '$coID' AND m.sender_uid = '$meID') )
    ORDER BY m.time DESC
  • $ meID是运行wuery的用户的iD,
  • $ coID是联系人的ID。

我有一个大问题,每次用户访问我的页面时都会运行。

SELECT  m2.message, m2.time, m2.sender_uid AS sender, m2.receiver_uid AS receiver, 
        m.contact, u.ufirstname
FROM (  SELECT  CASE
                WHEN sender_uid = '$me' THEN receiver_uid 
                ELSE sender_uid 
                END AS contact,
                MAX(time) AS maxtime
        FROM messages 
        WHERE sender_uid = '$me' OR receiver_uid = '$me'
        GROUP BY CASE
                 WHEN sender_uid = '$me' THEN receiver_uid 
                 ELSE sender_uid
                 END                                        ) AS m
INNER JOIN messages m2 ON m.maxtime = m2.time
AND ((m2.sender_uid = '$me' AND m2.receiver_uid = m.Contact)
OR (m2.receiver_uid = '$me' AND m2.sender_uid = m.Contact))
INNER JOIN users AS u ON m.contact = u.uid
ORDER BY time DESC
  • $ me是运行查询的用户的ID

此查询将(成功)检索:

LAST MESSAGE from EVERY 'CONVERSATION' ordered by TIME.

因此,它将在每个PM会话中获取最后一条消息(无论是发送还是接收消息) 而不是按时间排序,并检索联系人信息。

如果我没有正确解释,请告诉我。

我的MySQL表格如下:

receiver_id | sender_id | message | time

此查询会从哪些索引中受益?

(用户表已经在ID上有一个主键,因此联接检索联系人姓名的部分应该是有效的)

EXPLAIN OUTPUTs:

BIG查询:

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   PRIMARY     <derived2>  ALL     NULL    NULL    NULL    NULL    4   Using temporary; Using filesort
1   PRIMARY     m2  ALL     NULL    NULL    NULL    NULL    42  Using where
1   PRIMARY     u   eq_ref  PRIMARY     PRIMARY     4   m.contact   1   Using where
2   DERIVED     messages    ALL     NULL    NULL    NULL    NULL    42  Using where; Using temporary; Using filesort

更新部分中的查询:

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  u   const   PRIMARY     PRIMARY     4   const   1   Using index; Using filesort
1   SIMPLE  m   ALL     NULL    NULL    NULL    NULL    42  Using where

2 个答案:

答案 0 :(得分:0)

随着您的消息表的增长,此查询将开始变得越来越慢。根据用户所参与的会话数量,您将开始看到指数衰减的性能。虽然messages.time,messages.sender_uid和messages.receiver_uid上的单个索引现在有所帮助,但除非您修剪消息表,否则没有索引可以帮助您长期运行。特别是当你有超过几十万条消息时。

我建议维护一种将用户链接到对话及其最后一条消息ID的关联类型类型。看起来像:

user_id | conversation_id | MESSAGE_ID

然后,您可以查找此表,而不是执行复杂且昂贵的查询。这大大减少了您需要对消息表执行的扫描次数。虽然它确实略微增加了复杂性,但性能不会像上面的查询那样降低。

答案 1 :(得分:0)

我通过跟踪和错误发现索引时间减少了加载时间。 所以这可能是我的问题的答案。