如何通过查询加快分组

时间:2018-04-25 11:23:05

标签: mysql group-by

我有一个需要30秒才能运行的mysql查询。表格中有超过300万行

这是db结构:

text (VARCHAR(64)), 
kpi1 (INT), 
kpi2 (INT), 
position (DECIMAL),
date(DATE)
device (VARCHAR(32))

以下是查询:

select date, sum(kpi1), sum(kpi2) FROM  `table_name` GROUP BY date ;

解释方法给了我这个结果:

ID  | select type   | table        | partitions | type  | possible_keys  | key  | key_len | ref  | rows    | filtred | extra
1   | SIMPLE        | table_name   | NULL       | index | UNIQUE,DATE    | DATE | 3       | NULL | 3316480 | 100.00  | NULL

我有一个日期索引。

这里是分析结果:

mysql> show profile for query 1;
+----------------------+-----------+
| Status               | Duration  |
+----------------------+-----------+
| starting             |  0.000080 |
| checking permissions |  0.000011 |
| Opening tables       |  0.000021 |
| init                 |  0.000023 |
| System lock          |  0.000011 |
| optimizing           |  0.000007 |
| statistics           |  0.000021 |
| preparing            |  0.000019 |
| Sorting result       |  0.000007 |
| executing            |  0.000005 |
| Sending data         | 32.814836 |
| end                  |  0.000011 |
| query end            |  0.000009 |
| closing tables       |  0.000009 |
| freeing items        |  0.000082 |
| cleaning up          |  0.000013 |
+----------------------+-----------+
16 rows in set, 1 warning (0,00 sec)

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

如果历史日期的数据是静态的(因为日期/活动已经完成而未更改),那么这是何时使用摘要表的完美示例。创建一个单独的表,只需要日期和聚合就可以了。在当前所有日期之前执行此操作,因此仅在当天结束时,您插入(例如某些每日触发器)前一天的总和。你甚至可以包括记录的数量,比如

insert into MyDailySummaryTable 
   ( Date, kpi1Sum, kpi2Sum, numRecs )
   select date, 
          sum(kpi1) kpi1Sum, 
          sum(kpi2) kpi2Sum,
          count(*) numRecs
      FROM  
         `table_name` 
      where
         date < curdate()
      GROUP BY 
         date ;

然后是初始加载后的每一天

insert into MyDailySummaryTable 
   ( Date, kpi1Sum, kpi2Sum, numRecs )
   select date, 
          sum(kpi1) kpi1Sum, 
          sum(kpi2) kpi2Sum,
          count(*) numRecs
      FROM  
         `table_name` 
      where
         date = date_add( curdate(), interval -1 day )
      GROUP BY 
         date ;

如果你的日期&#34;字段也有时间戳信息,您可能需要调整查询以忽略时间部分。

然后,当您尝试运行总计时,您可以直接从MyDailySummaryTable进行查询并获得即时结果。

您甚至可以展开查询聚合表,以包含每台设备的计数,以防您想要查找该特定设备的跟踪信息。