我有一張名爲的表格,其中包含近1,5M行的DATA_TIMESLOTS。 表以這種方式取得:MYSQL GROUP BY PERFORMANCE
+-------+---------------+-----------+
| ID | SRV_TIMESTAMP | DEVICE_ID |
+-------+---------------+-----------+
| 134322| 1414583866 | A1323 |
| 134323| 1414583832 | B1423 |
| 134324| 1414583876 | A1323 |
| 134325| 1414583883 | B1423 |
| 134326| 1414583896 | A1323 |
| 134327| 1414583964 | C1524 |
| 134328| 1414581065 | A1323 |
| .... | ........ | ..... |
+-------+---------------+-----------+
ID是增量PK,SRV_TIMESTAMP和DEVICE_ID形式的羣集主鍵(如不同的DEVICE_ID可能具有相同的srv_timestamp ) 另一個名爲的表格包含了近1,5M行的DATA_RAW。這張桌子是這樣製作的:
+--------------+---------+---------+---------+---------+
| TIMESLOT_ID | POWER#1 | POWER#2 | POWER#3 | POWER#4 |
+--------------+---------+---------+---------+---------+
| 134322| 342532 | 354365 | 643654 | 77687 |
| 134323| 439642 | 269436 | 363466 | 16436 |
| 134324| 436252 | 326436 | 643645 | 31616 |
| 134325| 564326 | 867867 | 176471 | 16466 |
| 134326| 148585 | 643633 | 754277 | 43643 |
| 134327| 345298 | 754765 | 626364 | 32632 |
| 134328| 324898 | 532575 | 634366 | 65436 |
| .... | .. | .. | .. | .. |
+--------------+---------+---------+---------+---------+
顯然TIMESLOT_ID是這張表的PK。 正如你所看到的TIMESLOT_ID是第一個表的外鍵。 現在我需要獲得每天的統計數據如下:
SELECT
T.DEVICE_ID AS DEVICE_ID,
DAY(T.SRV_TIMESTAMP) AS SRV_DAY,
MONTH(T.SRV_TIMESTAMP) AS SRV_MONTH,
YEAR(T.SRV_TIMESTAMP) AS SRV_YEAR,
SUM(D.POWER#1) AS DAY_POWER#1,
SUM(D.POWER#2) AS DAY_POWER#2,
SUM(D.POWER#3) AS DAY_POWER#3,
SUM(D.POWER#4) AS DAY_POWER#4
FROM DATA_RAW AS D
INNER JOIN DATA_TIMESLOTS AS T ON T.ID=D.TIMESLOT_ID
GROUP BY
T.DEVICE_ID,
YEAR(T.SRV_TIMESTAMP),
MONTH(T.SRV_TIMESTAMP),
DAY(T.SRV_TIMESTAMP)
查詢工作正常,但它是令人難以置信的速度慢(64位4 CPU/4GB的機器上1.5米的記錄運行約60秒)。我懷疑,儘管我已經好放在DEVICE_ID,SRV_TIMESTAMP指標在DATA_TIMESLOTS領域表,這些索引是因爲DAY(),月無效(),YEAR()功能。所以我嘗試使用DATE()函數,但結果是一樣的。所以問題是:我是否需要在日期,月份,年份中添加其他字段,以便在表格上添加適當的索引並浪費一些空間以提高性能,或者還有另一種方法可以在沒有這樣的情況下獲得此結果浪費空間?
那麼我已經對我的SQLSERVER Express 2005(Microsoft)進行了一些測試,我不得不承認上述問題已完全解決。已經證實,在函數應用於鍵或索引後,MySQL無法保留鍵或索引。相當嚴重的限制恕我直言。 解決方案似乎是: 1)爲日,月,年添加3個附加字段 2)索引這些字段 3)在這些字段上創建羣組 另一方面,我認真考慮刪除時間戳字段在此之後完全沒用。我學到的教訓是,在MySQL時間戳類型中絕不能將它用作鍵或索引,比如對其應用函數時(如日,月,小時,年等),索引將被視爲無效...
你能爲此準備一個sqlfiddle嗎? – 2014-10-29 12:48:00
需要相當多的空間來通過上傳1,5百萬行來複制問題...沒有任何意義。 – 2014-10-29 13:54:12
它確實看到架構(表和索引),顯然它沒有意義上傳所有數據。也用'explain'顯示查詢計劃將會很有用 – 2014-10-29 17:57:02