2013-08-16 52 views
0

我有一個查詢,如果可能的話可以做優化,因爲它需要15秒運行。MySQL索引計算?

它正在查詢一個具有大約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` 
+0

如果你用'GROUP BY num,hour,mcstatus',它會更好嗎? MySQL可能會重複'DATE_FORMAT()',這是不必要的,因爲你已經在'SELECT'子句中做了這個。 – Barmar

+0

但一般的答案是,不可能像這樣對一個計算值進行索引。 – Barmar

+0

Mysql將使用'timestamp'作爲'hour'的索引 – bansi

回答

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