나는 젊은 개발자이고 데이터베이스 사용에 실제로 숙련되지 않았기 때문에 (PostgreSQL 9.3) 프로젝트에 문제가 발생하여 실제로 도움이 필요합니다.
내 프로젝트는 모든 장치가 초당 하나의 데이터 블록을 보내는 장치 (최대 1000 개 이상의 장치)에서 데이터를 수집하는 것입니다. 이는 시간당 약 3 백만 행을 만듭니다.
현재 모든 장치의 수신 데이터를 저장하는 하나의 큰 테이블이 있습니다.
CREATE TABLE data_block(
id bigserial
timestamp timestamp
mac bigint
)
데이터 블록에 포함 할 수 있거나 포함 할 수없는 여러 유형의 데이터가 있기 때문에 테이블을 참조하는 다른 테이블이 data_block있습니다.
CREATE TABLE dataA(
data_block_id bigserial
data
CONSTRAINT fkey FOREIGN KEY (data_block_id) REFERENCES data_block(id);
);
CREATE TABLE dataB(...);
CREATE TABLE dataC(...);
CREATE INDEX index_dataA_block_id ON dataA (data_block_id DESC);
...
하나의 data_block에는 3x dataA, 1x dataB가 있지만 dataC는 없을 수 있습니다.
데이터는 몇 주 동안 유지 되므로이 표에 ~ 50 억 행이 있습니다. 현재 테이블에 ~ 6 억 행이 있으며 쿼리에 시간이 오래 걸립니다. 그래서 select 문은 항상 시간이 지남에 따라 쿼리되고 종종 시간이 지남에 따라 쿼리되기 때문에 timestamp및에 인덱스를 만들기로 결정했습니다 mac.
CREATE INDEX index_ts_mac ON data_block (timestamp DESC, mac);
...하지만 내 쿼리는 여전히 오래 걸립니다. 예를 들어, 하루 동안 데이터와 하나의 맥을 쿼리했습니다.
SELECT * FROM data_block
WHERE timestamp>'2014-09-15'
AND timestamp<'2014-09-17'
AND mac=123456789
Index Scan using index_ts_mac on data_block (cost=0.57..957307.24 rows=315409 width=32) (actual time=39.849..334534.972 rows=285857 loops=1)
Index Cond: ((timestamp > '2014-09-14 00:00:00'::timestamp without time zone) AND (timestamp < '2014-09-16 00:00:00'::timestamp without time zone) AND (mac = 123456789))
Total runtime: 334642.078 ms
쿼리 실행 전에 완전히 진공 청소기로 청소했습니다. <10sec 미만의 쿼리를 수행하기 위해 큰 테이블로 이러한 문제를 해결하는 우아한 방법이 있습니까?
파티셔닝에 대해 읽었지만 data_block_id에 대한 dataA, dataB, dataC 참조에서 작동하지 않습니다. 어떻게 든 작동한다면 시간이 지남에 따라 또는 Mac을 통해 파티션을 만들어야합니까?
색인을 다른 방향으로 변경했습니다. 먼저 MAC, 타임 스탬프 및 많은 성능을 얻습니다.
CREATE INDEX index_mac_ts ON data_block (mac, timestamp DESC);
그러나 여전히 쿼리는 30 초 이상 걸립니다. 특히 LEFT JOIN데이터 테이블로 작업 할 때 . 다음은 EXPLAIN ANALYZE새로운 색인을 사용한 쿼리입니다.
EXPLAIN ANALYZE SELECT * FROM data_block WHERE mac = 123456789 AND timestamp < '2014-10-05 00:00:00' AND timestamp > '2014-10-04 00:00:00'
Bitmap Heap Scan on data_block (cost=1514.57..89137.07 rows=58667 width=28) (actual time=2420.842..32353.678 rows=51342 loops=1)
Recheck Cond: ((mac = 123456789) AND (timestamp < '2014-10-05 00:00:00'::timestamp without time zone) AND (timestamp > '2014-10-04 00:00:00'::timestamp without time zone))
-> Bitmap Index Scan on index_mac_ts (cost=0.00..1499.90 rows=58667 width=0) (actual time=2399.291..2399.291 rows=51342 loops=1)
Index Cond: ((mac = 123456789) AND (timestamp < '2014-10-05 00:00:00'::timestamp without time zone) AND (timestamp > '2014-10-04 00:00:00'::timestamp without time zone))
Total runtime: 32360.620 ms
불행히도 내 하드웨어는 엄격히 제한되어 있습니다. Intel i3-2100 @ 3.10Ghz, 4GB RAM을 사용하고 있습니다. 현재 설정은 다음과 같습니다.
default_statistics_target = 100
maintenance_work_mem = 512MB
constraint_exclusion = on
checkpoint_completion_target = 0.9
effective_cache_size = 4GB
work_mem = 512MB
wal_buffers = 16MB
checkpoint_segments = 32
shared_buffers = 2GB
max_connections = 20
random_page_cost = 2