a c*_*der 50 mysql optimization select temporary filesort
我正在开发一个事件跟踪系统,该系统使用少量查找表以及主要日志记录表.在我正在编写的报告中,可以选择一个对象来查看统计信息.界面按重要性降低(即命中)的顺序显示所有对象.
这两个表的架构(略微修剪,但你得到了要点):
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`)
);
Run Code Online (Sandbox Code Playgroud)
我遇到问题的查询如下.它与我的约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
Run Code Online (Sandbox Code Playgroud)
返回:
Using index; Using temporary; Using filesort
那么-有什么错我的架构和/或查询MySQL来依傍temporary和filesort?或者它是否使用ORDER BY进行了优化?
Ala*_*ins 86
好吧,文档给出了"使用临时"出现的确切原因:
可以在以下条件下创建临时表:
如果存在ORDER BY子句和不同的GROUP BY子句,或者ORDER BY或GROUP BY包含连接队列中第一个表以外的表中的列,则会创建临时表.
DISTINCT与ORDER BY结合使用可能需要临时表.
如果使用SQL_SMALL_RESULT选项,MySQL将使用内存中的临时表,除非查询还包含需要磁盘存储的元素(稍后描述).
快速扫描显示您患有#1.
而2009年的这篇博客称"使用filesort"意味着无法使用索引执行排序.由于您按计算字段进行排序,因此也是如此.
所以,这就是"错误".
针对MySQL 5.7(src)进行了更新:
服务器在以下条件下创建临时表:
评估UNION语句,稍后描述一些例外.
评估某些视图,例如使用TEMPTABLE算法,UNION或聚合的视图.
评估派生表(FROM子句中的子查询).
为子查询或半连接实现创建的表(请参见第8.2.2节"优化子查询,派生表和视图引用").
评估包含ORDER BY子句和不同GROUP BY子句的语句,或者ORDER BY或GROUP BY包含连接队列中第一个表以外的表中的列的语句.
评估DISTINCT结合ORDER BY可能需要临时表.
对于使用SQL_SMALL_RESULT修饰符的查询,MySQL使用内存中的临时表,除非查询还包含需要磁盘存储的元素(稍后描述).
为了评估从同一个表中选择和插入的INSERT ... SELECT语句,MySQL创建了一个内部临时表来保存SELECT中的行,然后将这些行插入到目标表中.请参见第13.2.5.1节"INSERT ... SELECT语法".
评估多表UPDATE语句.
评估GROUP_CONCAT()或COUNT(DISTINCT)表达式.