2017-09-28 30 views
0

大規模な風のシミュレーションを実行して、都市の時間風パターンを生成しています。結果は2次元の等高線の時系列である。現在、私は次のような構造2次元の時系列データをデータベース(sqlite3)に保存する最も効率的な方法

Table: CFD 
id, timestamp,   velocity, cell_id 
1 , 2010-01-01 08:00:00, 3.345, 1 
2 , 2010-01-01 08:00:00, 2.355, 2 
3 , 2010-01-01 08:00:00, 2.111, 3 
4 , 2010-01-01 08:00:00, 6.432, 4 
.., ..................., ....., . 
1000 , 2010-01-01 09:00:00, 3.345, 1 
1001 , 2010-01-01 10:00:00, 2.355, 2 
1002 , 2010-01-01 11:00:00, 2.111, 3 
1003 , 2010-01-01 12:00:00, 6.432, 4 
.., ..................., ....., . 

実際にSQLite3データベーステーブルに結果を格納してい文を作成します。

CREATE TABLE cfd(id INTEGER PRIMARY KEY, time DATETIME, u, cell_id integer) 
CREATE INDEX idx_cell_id_cfd on cfd(cell_id) 
CREATE INDEX idx_time_cfd on cfd(time) 

(これらのテーブルの3、異なる結果変数のそれぞれがあります)

ここで、cell_idは、都市内の場所を表すドメイン内のセルへの参照です。特定のタイムステップでどのように見えるかを知るには、この図を参照してください。 contour at timestep

典型的なクエリでは、時間ディメンションとグループの何らかの種類の集計がcell_idで実行されます。私は特定の時間間隔の間に各セルに平均局所風速を知りたい場合、例えば、私は、タイムスタンプの数は100から8,000まで変化させることができる

select sum(time in ('2010-01-01 08:00:00','2010-01-01 13:00:00','2010-01-01 14:00:00', ...................., ,'2010-12-30 18:00:00','2010-12-30 19:00:00','2010-12-30 20:00:00','2010-12-30 21:00:00') and u > 5.0) from cfd group by cell_id 

を実行することになります。

これは小さなデータベースでは問題ありませんが、大きなデータベースでは非常に遅くなります。たとえば、私の最後のデータベースは60GB、3つのテーブル、各テーブルには222,000,000行ありました。

データを保存する方法はありますか?たとえば、次のようになります。

  • 毎日別のテーブルを作成するのは意味がありますか?
  • タイムステップのために別のテーブルを使用し、結合を使用する方が良いでしょうか?
  • より良いインデックス作成方法はありますか?

パフォーマンスを最大限に高めるために、このquestionのすべての推奨事項を既に採用しています。

+0

実際のデータベース構造を示してください、そしてすべてのクエリをあなたは最適化する必要があります。 –

答えて

1

sum()はすべてのテーブル行に対して計算する必要があるため、この特定のクエリは最適化するのが難しいです。

SELECT count(*) 
FORM cfd 
WHERE time IN (...) 
    AND u > 5 
GROUP BY cell_id; 

可能な場合は、そのようtime BETWEEN a AND bとして、回をフィルタリングするために単純な式を使用します。WHEREで行をフィルタするには良いアイデアです。

すべてのクエリは、時間にclustered index(なし追加の索引)フィルタリングときcovering index、またはこのケースでは、使用する価値があるかもしれません:

CREATE TABLE cfd (
    cell_id INTEGER, 
    time DATETIME, 
    u, 
    PRIMARY KEY (cell_id, time) 
) WITHOUT ROWID; 
+0

最初のクエリの問題は、すべての 'cell_id'を返さないということです。私は少し前にクエリを書いていました。これが' count'ではなく 'sum'を使用した理由でした。私は明らかにランダムな実行時間を最小限のクエリ時間の2〜3倍の差で維持していますが、カバーインデックスはかなり役に立ちます。 'clustered index'を今すぐテストしてください。 – Rojj

+0

また、時間が必ずしも連続しているわけではないので、私は 'BETWEEN 'を使うことはできません。 – Rojj

+1

すべてのセルを取得したい場合は、 'sum'アプローチが最適です。しかし、これには表からすべての行を読み取る必要があります。これにより、カバーするかクラスタ化された索引を持つことがさらに重要になり、すべてのデータを検索しながら正しい順序で読み取ることができます。 –

関連する問題