当group by使用函数时,MySql优化组

时间:2014-02-24 13:47:54

标签: mysql innodb

我有一个带有以下架构的表hardBrake:

      -------------------- --------------------
     | Column Name        |  Type              |
      -------------------- --------------------
     |  id                | CHAR(36) primary   |
      -------------------- --------------------
     |  vehicleId         | CHAR(36)           |
      -------------------- --------------------
     |  address           | VARCHAR(50)        |
      -------------------- --------------------
     |  time              | TIMESTAMP          |
      -------------------- --------------------

现在,当我运行查询并尝试使用带有day()函数的时间列对其进行分组,并在select查询上使用EXPLAIN EXTENDED时,它使用临时和文件输出以及使用where和using index来显示。

我使用time + 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;

偏移字段和vehicleId字段我从我的java代码传递,该代码分别是用户时区和db时区之间的时区差异,分别是GMT和vehicleIds。

是否可以删除在函数???上使用group by的查询的临时文件和文件排序

我问题的潜行高峰:

我希望在他所在的时区为客户提供明确的事故。作为替代方案,我可以在java方面进行任何更改,而无需在mysql中使用时区。

1 个答案:

答案 0 :(得分:0)

恐怕这个查询无法避开临时表 请参阅此链接:http://dev.mysql.com/doc/refman/5.7/en/group-by-optimization.html

  

使用GROUP BY索引的最重要的前提条件是所有GROUP BY列引用同一索引的属性,并且索引按顺序存储其键.......

由于查询使用函数CONVERT_TZ(time,'+00:00', :offset)来获取GROUP BY值,MySql无法从索引中检索这些值,它必须使用该函数“动态”计算它们,并且必须将它们存储在临时值中表


同样的问题是filesort,
阅读此链接:http://dev.mysql.com/doc/refman/5.7/en/order-by-optimization.html

  

在某些情况下,MySQL无法使用索引来解析ORDER BY,尽管它仍然使用索引来查找与WHERE子句匹配的行。这些案件包括以下内容:
  ..........
  ..........
   - 您有不同的ORDER BY和GROUP BY表达式。

查询具有不同的GROUP BY和ORDER BY表达式:

group by day(dateOfIncident ) 
order by time DESC;

因此MySql无法使用索引,必须使用filesort。