-2

次のクエリにインデックスを使用しようとしていますが、結果はになりましたfilesort
パフォーマンスを向上させるために(ファイルソートを回避するために)クエリやインデックスをどのように変更する必要がありますか?

使ってみUNIONましたが、filesortまだ存在しています。

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 BY並べ替えがORDER BY必要です。データをソートせずに、MySQL が求めている結果を生成する方法はまったくありません。 filesort を使用すると、MySQL がデータ テーブルをソートします。先に進んでマシンに対して激怒しますが、マシンはあなたが要求したことを実行しています.

ファイルソートの代わりにインデックスソートを使用することもできますが、conversation. その列は、質問で示したインデックスの最初のコンポーネントとして表示されません。

何が起こったのかというと、サーバーは結合されたデータを一時テーブルに集めて並べ替える必要があります。これがどのように機能するかの説明については、MySQL / MariaDB 開発者の Sergey Petrunia のブログを参照してください。

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

GROUP BYまた、ステートメントには多くの非表示の列が含まれています。列をGROUP BY非表示にする機能は、MySQL に特有の (誤った) 機能です。これらの非表示の列は、サーバーが結合されたデータを収集し、別の手順で並べ替える理由の 1 つかもしれません。詳細については、MySQL マニュアルのこのページを参照してください。

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

出力にUsing filesortが表示される以外に、パフォーマンスの問題があることをどのように判断しますEXPLAINか? どのくらいのデータを処理していますか? どのくらいかかりますか?

于 2012-11-16T17:43:26.523 に答える