2015-04-27 35 views
0

這是我以前的帖子How to improve wind data SQL query performance的後續。使用算術和幾何計算加速SQL SELECT

我已經擴展了SQL語句,以執行使用circular statistics來計算平均風向的第一部分。這意味着我想計算風向的餘弦和正弦的平均值。在我的PHP腳本中,我將執行第二部分並計算反切線並在必要時添加180或360度。

風向存儲在我的表格中,因爲在'dirvolt'字段中從傳感器讀取電壓,所以我首先需要將其轉換爲弧度。

用戶可以通過使用分頁函數後退來查看歷史風力數據,因此使用LIMIT這些值是在我的PHP腳本中動態設置的。

我的SQL語句目前看起來是這樣的:

SELECT ROUND(AVG(speed),1) AS speed_mean, MAX(speed) as speed_max, 
     MIN(speed) AS speed_min, MAX(dt) AS last_dt, 
     AVG(SIN(2.04*dirvolt-0.12)) as dir_sin_mean, 
     AVG(COS(2.04*dirvolt-0.12)) as dir_cos_mean 
FROM table 
GROUP BY FLOOR(UNIX_TIMESTAMP(dt)/300) 
ORDER BY FLOOR(UNIX_TIMESTAMP(dt)/300) DESC 
LIMIT 0, 72 

查詢需要大約3-8秒,這取決於我使用的值對數據進行分組(在上面的代碼300)運行。

爲了讓我學習,有什麼我可以做的,以優化或改善SQL語句,否則?

+0

您正在使用哪個數據庫? – ipinak

+0

我猜你仍然使用與鏈接到的問題相同的數據庫... –

+0

你可以在該查詢上運行'EXPLAIN'嗎? –

回答

0
SHOW CREATE TABLE table; 

,從我可以看到,如果你已經有INDEX(dt)(或同等學歷)。由此,我們可以修改SELECT以顯着更快。

但首先,將焦點從72 * 300秒的讀數改變爲日期時間範圍,即6(?)小時。

讓我們看看這個查詢:

SELECT * FROM table 
    WHERE dt >= '...' - INTERVAL 6 HOUR 
     AND dt < '...'; 

'...'將在兩地相同的日期時間。這個索引運行速度是否足夠快?

如果是的話,那麼讓我們建立使用,作爲一個子查詢的最終查詢:

SELECT FORMAT(AVG(speed), 1) AS speed_mean, 
     MAX(speed) as speed_max, 
     MIN(speed) AS speed_min, 
     MAX(dt) AS last_dt, 
     AVG(SIN(2.04*dirvolt-0.12)) as dir_sin_mean, 
     AVG(COS(2.04*dirvolt-0.12)) as dir_cos_mean 
    FROM 
     (SELECT * FROM table 
      WHERE dt >= '...' - INTERVAL 6 HOUR 
      AND dt < '...' 
    ) AS x 
    GROUP BY FLOOR(UNIX_TIMESTAMP(dt)/300) 
    ORDER BY FLOOR(UNIX_TIMESTAMP(dt)/300) DESC; 

說明:你有什麼不能使用索引,因此不得不掃描整個表(這是越來越大,大)。我的子查詢可以使用索引,因此速度更快。因爲它只處理了N行,所以我的外部查詢的工作並不是「太糟糕」。

+0

謝謝瑞克,我非常感謝你的幫助!我確實將dt添加爲主索引。用嵌套的SELECT替換LIMIT(僅用於創建6小時的數據)到您的建議之後,查詢的執行時間從4.2秒減少到0.008。驚人!我將重寫分頁實現以代替dt。 – Watts