MySQL索引计算?

时间:2013-08-16 05:00:37

标签: mysql indexing query-optimization

我有一个查询,如果可能,可以进行优化,因为它需要15秒才能运行。

它正在查询一个包含大约1000000条记录的大型数据库,并通过按小时分组(从DATE_FORMAT()派生)来减慢速度。

我索引了所有表格中的所有相关字段,这些字段显着提高了性能,但我不知道如何或者是否可以为小时组创建索引,因为它不是字段...

我确实知道数据集非常大,但我想知道我是否有任何选择。

任何帮助将不胜感激! 谢谢!

SELECT  `id`,
    tbl1.num,
    name,
    DATE_FORMAT(`timestamp`,'%x-%v') AS wknum,
    DATE_FORMAT(`timestamp`,'%Y-%m-%d') AS date,
    DATE_FORMAT(`timestamp`,'%H') as hour,
    IF(code<>0,codedescription,'') AS status,
    SUM(TIME_TO_SEC(`timeblock`))/60 AS time, 
    SUM(`distance`) AS distance, 
    SUM(`distance`)/(SUM(TIME_TO_SEC(`timeblock`))/60) AS speed
FROM  `tbl1`
LEFT JOIN `tbl2` ON tbl1.code = tbl2.code 
LEFT JOIN `tbl3` ON tbl1.status = tbl3.status 
LEFT JOIN `tbl4` ON tbl1.conditionnum = tbl4.conditionnum 
LEFT JOIN `tbl5` ON tbl1.num = edm_mc_list.num
WHERE `timestamp`>'2013-07-28 00:00:00'
GROUP BY `num`,DATE_FORMAT(`timestamp`,'%H'),`mcstatus`

1 个答案:

答案 0 :(得分:1)

MySQL通常不能在列上使用索引,除非列是 在查询中隔离。 隔离列意味着它不应该是表达式的一部分,也不应该位于查询中的函数内。

解决方案:

1 - 您可以与timestamp列分开存储小时。例如,您可以通过before insertbefore update触发器存储它。

DELIMITER $$
CREATE TRIGGER `before_update_hour`
BEFORE UPDATE ON `tbl1`
FOR EACH ROW
BEGIN
     IF NEW.`timestamp` != OLD.`timestamp` THEN
       SET NEW.`hour` = DATE_FORMAT( NEW.`timestamp`,'%H')
     END IF;
END;
$$
DELIMITER ;

 DELIMITER $$
 CREATE TRIGGER `before_insert_hour`
 BEFORE INSERT ON `tbl1`
 FOR EACH ROW
 BEGIN
     SET NEW.`hour` = DATE_FORMAT( NEW.`timestamp`,'%H')
 END;
 $$
 DELIMITER ;

2 - 如果您可以使用MariaDB,则可以使用MariaDB virtual columns