2017-09-28 5 views
0

대도시에서 시간별 바람 패턴을 생성하기 위해 대규모 바람 시뮬레이션을 수행하고 있습니다. 결과는 2 차원 외곽선의 시계열입니다. 현재 나는 다음과 같은 구조로 SQLite3 데이터베이스 테이블에 결과를 저장하고데이터베이스 (sqlite3)에 2-D 시계열을 저장하는 가장 효율적인 방법은 무엇입니까

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 개였습니다.

데이터를 저장하는 더 좋은 방법이 있습니까? 예 :

  • 매일 다른 테이블을 만드는 것이 합리적일까요?
  • timesteps에 대해 별도의 테이블을 사용한 다음 조인을 사용하는 것이 더 좋을까요?
  • 더 좋은 색인 생성 방법은 무엇입니까?

성능을 최대화하기 위해 이미 question에있는 모든 권장 사항을 채택했습니다.

+0

실제 데이터베이스 구조를 보여주십시오, 모든 쿼리를 최적화가 필요합니다. –

답변

1

이 특정 쿼리는 모든 테이블 행에 대해 sum()을 계산해야하기 때문에 최적화하기가 어렵습니다. WHERE와 행을 필터링하는 좋은 아이디어입니다 :

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

가능한 경우는, 같은 time BETWEEN a AND b 배를 필터링하는 간단한 표현을 사용합니다.

모든 쿼리가 시간에 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 배의 차이로 무작위 실행 시간을 계속 유지하지만 상당히 도움이됩니다. '클러스터 된 인덱스 '테스트. – Rojj

+0

또한, 반드시 연속적 일 필요는 없으므로 'BETWEEN'을 사용할 수 없습니다. – Rojj

+1

모든 셀을 가져 오려면'sum' 접근 방식이 가장 좋습니다.그러나이를 위해서는 테이블의 모든 행을 읽어야합니다. 따라서 모든 데이터를 검색 할 때 올바른 순서로 읽을 수 있도록 덮고 있거나 클러스터 된 인덱스를 갖는 것이 더 중요합니다. –