2012-04-03 4 views
5

私は単純なMySQLクエリを使用していますが、ORDER BYを使用しているためパフォーマンスが悪いです。 MySQLがfilesortとtemporaryをなぜ使用しているのか分かりません。filesortとテンポラリを使用したMySQLクエリ

私のクエリは次のとおりです。

Table Events structure

表イベントインデックス

Mysql EXPLAIN output

表イベント構造:

EXPLAIN 
SELECT * FROM Events 
INNER JOIN EventLogFiles ON ServerID = 42 
AND Events.LogFileID = EventLogFiles.LogFileID 
ORDER BY ReportID DESC , TimeWritten DESC 
LIMIT 100 

これはEXPLAINの出力であります

Table Events indexes

表のEventLogFiles構造

Table EventLogFiles structure

表のEventLogFilesインデックス

Table EventLogFiles indexes

UPDATE:

私は、2つの新しいを作成しようとしましたしかし、どちらも、MySQLにfilesortとtemporaryを強制的に使用させます。

ALTER TABLE Events ADD INDEX `ReportID_TimeWritten_ServerID_LogFileID` (ReportID DESC, TimeWritten DESC, ServerID, LogFileID) 

ALTER TABLE Events ADD INDEX `ServerID_LogFileID_ReportID_TimeWritten` (ServerID, LogFileID, ReportID DESC, TimeWritten DESC) 
+1

注文を行わずに最初の100レコードをテンポラリテーブルに出力し、別のクエリを使用して100レコードだけを注文できますか? –

+1

Events.LogFileIDを複数列のインデックスに追加します。 –

+0

インデックス 'ServerID_ReportID_TimeWritten_LogFileID'、 'ReportID_TimeWritten_ServerID_LogFileID'を作成してみることができますか?私は彼らの一人が助けになると思います。 –

答えて

4

選択とソートの両方のインデックスを利用するために、あなたはイベントのマルチカラムインデックスに次の列のすべてを持っている必要があります:(ServerID, LogFileID, ReportID, TimeWritten)

現在、ON節にあるLogFileIDが含まれていないため、MySQLは既存のマルチカラムインデックスを利用できません。

MySQLがEventLogFilesから最初に選択している問題が発生した場合は、INNER JOINSTRAIGHT JOINに変更して、MySQLが常にイベントから最初にインデックスを使用するようにすることができます。

+0

マーカス、私はあなたのアドバイスに従ったが、同じ問題がある、あなたはアイデアを持っていますか? キー:ServerID_LogFileID_ReportID_TimeWritten | key_len:4 |追加:一時的な使用。 filesortの使用 – koen

+0

複数列インデックスの場合、Key_lenは4にすることはできません。それは16でなければなりません。私はあなたのクエリとインデックスを再確認します。 –

0

あなたは、一時テーブルとファイルの並べ替えなしにしなければならない作業はあなたがそうORDER BY ReportID(PK - Order Physical)あなたがfilesortレコードを削除する必要があり作り、ReportIDに使用されているauto_incrementのようなシーケンシャルであることをインデックス(ServerID, LogFileID, ReportID)TimeWritten必見を作成することを得るために。

関連する問題