2017-07-06 33 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 + dateのインデックスを追加すると、クエリでこれを使用できるようになり、非常に高速になります。しかし、テーブルの記憶域も大きくなり、すべての日付値をインデックス化することは有用ではありません。私は最大値にのみ関心を持っています。

だから私の質問は、最大値を追跡するのに理想的には、ある範囲のインデックスを作成するインデックスを作成することが可能な場合です。

+4

この情報を別のテーブルに保存するほうがよいでしょう。たとえば、 'Stations'テーブルのように、行を挿入するたびに情報を更新するトリガを使用する方がよいでしょう。 –

+1

PKを 'station + date + metric'に変更できますか?機能的には同じことになりますが、実際には余分なインデックスを追加した場合とほぼ同じくらい速くなります。 – deroby

+0

@deroby私はそれを試して、実際にはクエリが即座に実行されます。しかし、もう1つの頻繁なクエリ、「1つのステーションの1つの気分の1週間の値をリストする」のようなクエリは、遅く実行されるようになりました(それほど多くはなく、約25%遅くなりました)。私のアプリケーションで最後のものがはるかに頻繁になることを考えれば、私は以前の主キーにとどまります。ありがとう! –

答えて

1

わかりません。しかし、あなたには別の解決策があります。

他のデータベースでは、マテリアライズド・ビューを推奨しますが、マテリアライズド・ビュー(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)に並べ替えることもできます。

また、その日にtempを使用する場合は、より複雑なgroupwise-maxになります。