在数据库中存储2-D时间序列的最有效方法是什么(sqlite3)

时间:2017-09-28 20:50:56

标签: database database-design sqlite time-series

我正在进行大规模的风力模拟,以便在城市上产生每小时的风力模式。结果是二维轮廓的时间序列。目前,我将结果存储在具有以下结构的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 
.., ..................., .....,    .

实际创建声明:

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)

(这些表中有三个,每个表用于不同的结果变量)

其中cell_id是对域中代表城市中某个位置的单元格的引用。请参阅此图片,了解特定时间步长的效果。contour at timestep

典型的查询在时间维度上执行某种聚合,并在cell_id上执行分组。例如,如果我想知道特定时间间隔内每个小区的平均局部风速,我会执行

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

时间戳的数量可以在100到8,000之间变化。

这适用于小型数据库,但对于大型数据库来说速度要慢得多。例如,我的最后一个数据库是60GB,3个表,每个表有222,000,000行。

有更好的方法来存储数据吗?例如:

  • 为每天创建一个不同的表是否有意义?
  • 最好为时间步长使用单独的表,然后使用连接?
  • 有更好的索引方法吗?

我已采用此question中的所有建议来最大限度地提高效果。

1 个答案:

答案 0 :(得分:1)

此特定查询很难优化,因为必须在所有表行上计算sum()。最好使用WHERE:

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

如果可能,请使用更简单的表达式来过滤时间,例如time BETWEEN a AND b

使用covering index可能是值得的,或者在这种情况下,当所有查询按时间过滤时,clustered index(没有其他索引):

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