我正在开发一个事件跟踪系统,该系统使用少数查找表以及主日志记录表。在我撰写的报告中,可以选择一个对象来查看统计信息。界面按重要性递减的顺序显示所有对象(即命中)。
两个表的架构(略有减少,但您能理解以下要点):
CREATE TABLE IF NOT EXISTS `event_log` ( `event_id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(5) DEFAULT NULL, `object_id` int(5) DEFAULT NULL, `event_date` datetime DEFAULT NULL, PRIMARY KEY (`event_id`), KEY `user_id` (`user_id`), KEY `object_id` (`object_id`) ); CREATE TABLE IF NOT EXISTS `lookup_event_objects` ( `object_id` int(11) NOT NULL AUTO_INCREMENT, `object_desc` varchar(255) NOT NULL, PRIMARY KEY (`object_id`) );
我遇到问题的查询如下。我的〜100个条目的表可以正常工作,但是EXPLAIN令我有些担心。
explain SELECT el.object_id, leo.object_desc, COUNT(el.object_id) as count_rows FROM event_log el LEFT JOIN lookup_event_objects leo ON leo.object_id = el.object_id GROUP BY el.object_id ORDER BY count_rows DESC, leo.object_desc ASC
返回值: Using index; Using temporary; Using filesort
Using index; Using temporary; Using filesort
那么-有什么错我的架构和/或查询MySQL来依傍temporary和filesort?还是使用ORDER BY获得的优化?
temporary
filesort
好吧,文档给出了出现“使用临时”时的确切原因:
可以在以下条件下创建临时表: 如果有一个ORDER BY子句和另一个GROUP BY子句,或者ORDER BY或GROUP BY包含联接队列中第一个表以外的表中的列,则会创建一个临时表。 DISTINCT与ORDER BY结合使用可能需要一个临时表。 如果使用SQL_SMALL_RESULT选项,则MySQL使用内存中临时表,除非查询还包含需要磁盘存储的元素(稍后描述)。
可以在以下条件下创建临时表:
如果有一个ORDER BY子句和另一个GROUP BY子句,或者ORDER BY或GROUP BY包含联接队列中第一个表以外的表中的列,则会创建一个临时表。
DISTINCT与ORDER BY结合使用可能需要一个临时表。
如果使用SQL_SMALL_RESULT选项,则MySQL使用内存中临时表,除非查询还包含需要磁盘存储的元素(稍后描述)。
快速扫描显示您患有#1。
而这个博客从2009年说:“使用文件排序”指的是那种不能用指数来进行。由于您要按计算字段排序,所以这也将是正确的。
因此,这就是“错误”。