2017-06-21 180 views
0

下面的查詢工作,但是非常計算昂貴(有> 14k條記錄);這可以更有效地完成(例如,沒有嵌套查詢)? 基本上它與同一個表中的實例相匹配,它們代表開啓命令(log1)和第一個關閉命令(log2)。SQL查詢:這可以在沒有嵌套查詢的情況下完成嗎?

SELECT log1.`deviceID`, log1.`timestamp` AS `on`, log2.`timestamp` as `off` 
FROM `HC2_log_raw` log1, `HC2_log_raw` log2 
WHERE log1.`newValue` > 0 AND log1.`oldValue` = 0 AND log2.`newValue` = 0 AND log1.`deviceID` = log2.`deviceID` AND 
    log2.`timestamp` = 
    (SELECT MIN(log3.`timestamp`) 
    FROM `HC2_log_raw` log3 
    WHERE log3.`timestamp` > log1.`timestamp` AND log3.`deviceID` = log1.`deviceID` AND log3.`newValue`=0) 

謝謝!

+0

14K記錄並不是很多。 你有沒有看過執行計劃? 您可能只是需要一個索引 –

+0

您是否在連接條件列上使用索引? –

+0

它不會幫助性能,但是您應該切換到明確的'join'語法,這是自1992年以來的ANSI標準! – HoneyBadger

回答

0

你可以嘗試使用JOIN GROUP BYMIN功能存檔您預期的結果

SELECT log1.`deviceid`, 
     log1.`timestamp`  AS `on`, 
     MIN(log2.`timestamp`) AS `off` 
FROM `hc2_log_raw` log1 
     INNER JOIN `hc2_log_raw` log2 
       ON log1.`deviceid` = log2.`deviceid` 
        AND log1.`timestamp` < log2.`timestamp` 
WHERE log1.`newvalue` > 0 
     AND log1.`oldvalue` = 0 
     AND log2.`newvalue` = 0 
GROUP BY log1.`deviceid`, log1.`timestamp` 
+0

謝謝!像魅力一樣工作,速度大約快5倍:)感謝所有其他評論,我仍然需要創建適當的索引,這會使其更快! – 3JL

+0

deviceid和timestamp上的索引僅將速度提高20%btw – 3JL

+0

您是否嘗試在newvalue和oldvalue字段上創建索引? –

0

檢查了這一點。 afaik,where子句比加入on條件更好。

SELECT log1.`deviceID` 
    ,log1.`timestamp` AS `on` 
    ,log2.`timestamp` AS `off` 
FROM 
`HC2_log_raw` log1 
inner join `HC2_log_raw` log2 
on 
log1.`deviceID` = log2.`deviceID` 
where 
(
    log1.`newValue` > 0 
AND log1.`oldValue` = 0 
AND log2.`newValue` = 0 
AND log2.`timestamp` = (
     SELECT MIN(log3.`timestamp`) 
     FROM `HC2_log_raw` log3 
     WHERE log3.`timestamp` > log1.`timestamp` 
      AND log3.`deviceID` = log1.`deviceID` 
      AND log3.`newValue` = 0 
     ) 
)