-2

我正在尝试对以下查询使用索引,但结果是filesort.
我应该如何更改查询和/或索引以提高性能(避免文件排序)?

我尝试使用UNIONfilesort仍然存在。

CREATE TABLE message (  
  Ms_ID INT(16) UNSIGNED NOT NULL AUTO_INCREMENT, 
  conversation INT(16) UNSIGNED NOT NULL, 
  subject ENUM('E', 'F', 'S-C', 'S-A', 'R-RS', 'R-ILP', 'Re-M', 'Re-I', 'Re-R', 'O', 'SP', 'T', 'I', 'C', 'Of', 'R') DEFAULT NULL, 
  subject_ID INT(16) UNSIGNED DEFAULT NULL, 
  sender INT(11) UNSIGNED, -- NULL=guest
  recipient INT(11) UNSIGNED NOT NULL, 
  message VARCHAR(256), 
  status ENUM('U','R','SD', 'RD', 'SRD'), -- (unread, read, sender deleted, recipient deleted) 
  dateTime DATETIME NOT NULL,   
  PRIMARY KEY (Ms_ID), 
  FOREIGN KEY (sender) REFERENCES member (M_ID),
  FOREIGN KEY (recipient) REFERENCES member (M_ID)


CREATE INDEX xMs_C ON message (conversation, sender, recipient, status, subject, dateTime)
CREATE INDEX xMs_D ON message (dateTime, conversation, recipient, sender, status, message)
CREATE INDEX xMs_R ON message (recipient, sender, status, dateTime, message)
CREATE INDEX xMs_S ON message (sender, recipient, status, dateTime, message)


EXPLAIN
  SELECT Ms.*, M.userName   
  FROM message Ms -- FORCE INDEX (xMs_S)
    INNER JOIN member M ON M_ID=IF (sender='3', recipient, sender)
  WHERE Ms.status!='SRD' AND ((sender='3' AND Ms.status!='SD') OR (recipient='3' AND Ms.status!='RD')) 
  GROUP BY conversation   
  ORDER BY dateTime DESC

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  Ms  ALL     xMs_S   NULL    NULL    NULL    77  Using where; Using temporary; Using filesort
1   SIMPLE  M   eq_ref  PRIMARY     PRIMARY     4   func    1   Using where
4

2 回答 2

0

你可以尝试这样的事情:

SELECT *

FROM

(
SELECT Ms.*, M.userName   
FROM message Ms -- FORCE INDEX (xMs_S)
    INNER JOIN member M ON M_ID = recipient
  WHERE Ms.status!='SRD' AND sender='3' AND Ms.status!='SD' 

UNION ALL

SELECT Ms.*, M.userName   
FROM message Ms -- FORCE INDEX (xMs_S)
    INNER JOIN member M ON M_ID = sender
  WHERE Ms.status!='SRD' recipient='3' AND Ms.status!='RD'
) a

GROUP BY conversation   
ORDER BY dateTime DESC;
于 2012-11-16T17:15:20.470 回答
0

GROUP BYORDER BY要求分类;如果不对数据进行排序,MySQL 根本无法产生您要求的结果。 使用文件排序意味着 MySQL 正在对您的数据表进行排序。继续对机器大发雷霆,但它正在做你要求它做的事情。

它可能使用索引排序而不是文件排序,但您按conversation. 该列不会作为您在问题中显示的任何索引的第一个组成部分出现。

发生的事情是服务器必须将您连接的数据收集到一个临时表中以对其进行排序。查看 MySQL / MariaDB 开发人员的 Sergey Petrunia 的博客,了解其工作原理。

http://s.petrunia.net/blog/?p=24

您还在GROUP BY语句中包含了许多隐藏的列。GROUP BY隐藏列的能力是 MySQL 独有的(错误)功能。这些隐藏的列可能是服务器收集您的连接数据然后在不同步骤中对其进行排序的原因之一。阅读 MySQL 手册的这一页以了解更多信息。

http://dev.mysql.com/doc/refman/5.6/en/group-by-hidden-columns.html

除了在输出中看到Using filesortEXPLAIN之外,你怎么知道你遇到了性能问题?您正在处理多少数据?需要多长时间?

于 2012-11-16T17:43:26.523 回答