将索引添加到生成的列

时间:2014-10-16 15:11:24

标签: mysql indexing group-by denormalization

首先,对不起,如果使用的条款不对。我不是mySQL专业人士。

我有一张这样的表:

CREATE TABLE `accesses` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `time` int(11) DEFAULT NULL,
  `accessed_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `index_accesses_on_accessed_at` (`accessed_at`)
) ENGINE=InnoDB AUTO_INCREMENT=9278483 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

此表格中包含 10.000.000 行。我用它来生成图表,查询如下:

SELECT SUM(time) AS value, DATE(created_at) AS date
FROM `accesses`
GROUP BY date;

此查询非常长(超过1分钟)。我做了很多其他查询(AVGMINMAX代替SUM,或在特定日期使用WHERE或月,或GROUP BY HOUR(created_at)等等......)

我想优化它。 我最好的想法是添加多个具有冗余的列,例如DATE(created_at)HOUR(created_at)MONTH(created_at),然后在其上添加索引。

......这个解决方案是好还是还有其他解决方案?

此致

1 个答案:

答案 0 :(得分:2)

是的,可以优化将数据冗余地存储在永久列中,并使用索引来优化某些查询。这是非规范化的一个例子。

根据数据量和查询频率,这可能是一个重要的加速(@Marshall Tigerus过分夸大,恕我直言)。

我通过运行EXPLAIN测试了这个:

mysql> explain SELECT SUM(time) AS value, DATE(created_at) AS date FROM `accesses` GROUP BY date\G                      *************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: accesses
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 1
     filtered: 100.00
        Extra: Using temporary; Using filesort

忽略我的测试中表格为空的事实。重要的部分是Using temporary; Using filesort这是昂贵的操作,特别是如果你的临时表变得如此之大以至于MySQL无法在内存中使用它。

我在它们上添加了一些列和索引:

mysql> alter table accesses add column cdate date, add key (cdate), 
  add column chour tinyint, add key (chour), 
  add column cmonth tinyint, add key (cmonth);

mysql> explain SELECT SUM(time) AS value, cdate FROM `accesses` GROUP BY cdate\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: accesses
   partitions: NULL
         type: index
possible_keys: cdate
          key: cdate
      key_len: 4
          ref: NULL
         rows: 1
     filtered: 100.00
        Extra: NULL

临时表和filesort消失了,因为MySQL知道它可以进行索引扫描以正确的顺序处理行。