使用filesort和临时的MySQL查询
我正在使用一个简单的MySQL查询,但由于使用ORDER BY,性能实际上很糟糕。我无法弄清楚为什么MySQL使用filesort和临时。使用filesort和临时的MySQL查询
我的查询是:
EXPLAIN
SELECT * FROM Events
INNER JOIN EventLogFiles ON ServerID = 42
AND Events.LogFileID = EventLogFiles.LogFileID
ORDER BY ReportID DESC , TimeWritten DESC
LIMIT 100
这是EXPLAIN输出:
表活动结构
表活动指数
表EventLogFiles结构
表EventLogFiles指标
UPDATE:
我试图创建两个新索引,但两者仍然强制MySQL使用filesort和临时的。
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)
为了利用指数都选择和排序,你需要有所有对事件进行了多列索引以下列:(ServerID, LogFileID, ReportID, TimeWritten)
。
目前,MySQL不能利用现有的多列索引,因为它不包含LogFileID
,它在ON
子句中。
如果您在MySQL中首先从事件日志文件中选择时遇到问题,您可以将INNER JOIN
更改为STRAIGHT JOIN
,以确保MySQL始终首先使用您的索引从事件中选择事件。
Marcus,我遵循你的建议,但仍然是同样的问题,你有什么想法吗? 注意:ServerID_LogFileID_ReportID_TimeWritten | key_len:4 |额外:使用临时;对于多列索引,使用filesort – koen 2012-04-03 20:20:34
Key_len不能为4。它应该是16.我会仔细检查您的查询和索引。 – 2012-04-04 19:16:24
为了获得,没有临时表和文件类型的工作,你必须创建一个索引(ServerID, LogFileID, ReportID)
和TimeWritten
必须是连续的一样,你一直使用ReportID
的auto_increment
,所以使得ORDER BY ReportID(PK - Order Physical)
必须删除文件排序。
您可以在不订购的情况下将前100个记录输出到临时表,然后仅使用另一个查询来排序这100个记录? – 2012-04-03 19:07:32
将Events.LogFileID添加到多列索引。 – 2012-04-03 19:17:21
你可以尝试创建索引'ServerID_ReportID_TimeWritten_LogFileID','ReportID_TimeWritten_ServerID_LogFileID'?我认为其中之一会有所帮助。 – 2012-04-03 19:18:02