我有一个具有以下架构的硬刹车表:
-------------------- --------------------
| Column Name | Type |
-------------------- --------------------
| id | CHAR(36) primary |
-------------------- --------------------
| vehicleId | CHAR(36) |
-------------------- --------------------
| address | VARCHAR(50) |
-------------------- --------------------
| time | TIMESTAMP |
-------------------- --------------------
现在,当我运行查询并尝试使用时间列和 day() 函数对其进行分组并在选择查询上使用 EXPLAIN EXTENDED 时,它显示使用临时和文件排序以及使用 where 和使用索引。
我使用时间+vehicleId列作为索引,我的选择查询是:
select count(1),CONVERT_TZ(time,'+00:00', :offset) as dateOfIncident
from hardBrake
where vehicleId in (vehicleIds)
and time between NOW() - INTERVAL 30 DAY and NOW()
group by day(dateOfIncident )
order by time DESC;
我从我的java代码传递的offset字段和vehicleId字段是用户时区和数据库时区之间的时区差,分别采用GMT和客户的vehicleIds。
是否可以删除在函数上使用 group by 的查询的临时和文件排序???
我的问题的概要:
我想为客户在他的时区的日期提供硬刹车事件。作为替代方案,我可以在 java 端进行任何更改,而不必在 mysql 中查找时区。
最佳答案
恐怕这个查询无法避免临时表。
引用此链接:http://dev.mysql.com/doc/refman/5.7/en/group-by-optimization.html
The most important preconditions for using indexes for GROUP BY are that all GROUP BY columns reference attributes from the same index, and that the index stores its keys in order .....
由于查询使用函数CONVERT_TZ(time,'+00:00', :offset)
来获取GROUP BY值,MySql无法从索引中检索这些值,它必须计算它们“即时”使用该函数,并且必须将它们存储在临时表中。
文件排序也有同样的问题,
阅读此链接:http://dev.mysql.com/doc/refman/5.7/en/order-by-optimization.html
In some cases, MySQL cannot use indexes to resolve the ORDER BY, although it still uses indexes to find the rows that match the WHERE clause. These cases include the following:
..........
..........
- You have different ORDER BY and GROUP BY expressions.
查询具有不同的 GROUP BY 和 ORDER BY 表达式:
group by day(dateOfIncident )
order by time DESC;
因此MySql不能使用索引,必须使用文件排序。
关于MySql优化group by时group by使用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21989651/