2017-07-06 107 views
0

我有一個巨大的表格,有數百萬行存儲從某些氣象站獲得的值。每行包含收集數值的站點,度量(例如,溫度,噪音水平等),日期和數值本身。只有最大值和最小值的MySQL索引

這是它的結構:

  • station:INT(8)
  • metric:INT(8)
  • date:日期時間
  • value:浮動

而這些是我定義的指數:

  • PRIMARY KEY:station+metric+date
  • KEY:metrica(外鍵)

有時候,我感興趣的檢索最後一次每站都有送一些價值。然後我使用這個查詢:

SELECT station, MAX(date) 
FROM MyTable 
GROUP BY station 

這個查詢非常慢,因爲它必須讀取整個表。如果我爲station +日期添加索引,則查詢現在可以使用它並且變得非常快。但是表格存儲也增加了很多,對於我來說索引所有的日期值並沒有用,因爲我只對最大值感興趣。

所以我的問題是如果有可能創建一個索引來索引一些範圍,理想情況下只跟蹤最大值。

+4

您可能會更好地將這些信息存儲在另一個表格中 - 比如說「Stations」表格 - 並且使用觸發器在每次插入行時更新信息。 –

+1

您可以將PK更改爲「station + date + metric」嗎?在功能上它會是同樣的東西,但實際上它會(幾乎)與添加額外索引時的情況一樣快。 – deroby

+0

@deroby我試過了,實際上這個查詢會立即運行。但是另一個頻繁的查詢,例如「列出一個站的溫度值的一週值」現在執行得更慢(不是很多,大約慢了25%)。鑑於我的應用程序中最後一個更頻繁,我將繼續使用以前的主鍵。謝謝! –

回答

1

不是我所知道的。但你有其他解決方案。

在其他數據庫中,我建議使用物化視圖,但MySQL不支持物化視圖(SO#3991912),因此您必須創建並管理自己的聚合表。

如果您的源表未更新太頻繁,CREATE TABLE last_observation AS SELECT station, MAX(date) AS date FROM observations GROUP BY station將執行此項工作。只需在任何相關請求之前發表聲明即可。

如果您的服務器有足夠的資源,您可以離開表格MEMORY,以獲得超快的響應。在這種情況下,您需要明確列出CREATE TABLE last_observation (station VARCHAR(x), lastDate DATE) ENGINE=MEMORY AS SELECT station, MAX(date) AS lastDate FROM observations GROUP BY station列。當然,每次打開mysql時都應該定期發佈這個聲明。

如果您的表經常更新,您可以使用源表(Full tutorial here)上的觸發器管理內容。

另一種完全不同的方法是使用列式數據庫。幾年前我們使用了Infobright,它有一個免費的社區版本,對你來說是完全透明的(只需安裝它並像以前一樣使用mysql)。

0
INDEX(station, date) 

將有效地處理查詢。或者,您可以將PRIMARY KEY重新排列爲(station, date, metric)

如果您還想在該日期的溫度,那麼你是一個更復雜的groupwise-max

相關問題