매초마다 많은 삽입이있는 거대한 테이블 (현재 3mil 행, 계수가 1000만큼 증가 할 것으로 예상 됨)이 있습니다. 테이블은 절대로 업데이트되지 않습니다.Postgres : (지연된) 읽기 및 쓰기 액세스가있는 거대한 테이블
이제 예상대로 꽤 느린 테이블에서 쿼리를 실행해야합니다. 이러한 쿼리는 100 % 정확할 필요는 없지만 결과가 하루 이전이지만 오래된 것은 아닙니다.
현재 두 개의 단일 정수 열에 두 개의 인덱스가 있고 쿼리 속도를 높이기 위해 두 개의 인덱스 (정수 및 타임 스탬프 열)를 추가해야합니다. 내가 지금까지 한
아이디어 :
- 전혀 거대한 테이블에 테이블에
- 없음 인덱스를 두 누락 된 인덱스를 추가 및 두 번째 테이블에 (매일 작업으로) 내용을 복사 (단지 중요한 행) 다음 두 번째 테이블에 인덱스를 만들고 해당 테이블에 대한 쿼리를 실행?
- 거대한 테이블을 파티션하기
- 마스터/슬레이브 설정 (마스터에 쓰고 슬레이브에서 읽음).
성능면에서 어떤 옵션이 가장 좋습니까? 다른 제안이 있으십니까?
EDIT : 여기
는 테이블 (I는 외부 키를 표시하고 쿼리 비트 prettified있다)
CREATE TABLE client_log
(
id serial NOT NULL,
logid integer NOT NULL,
client_id integer NOT NULL, (FOREIGN KEY)
client_version varchar(16),
sessionid varchar(100) NOT NULL,
created timestamptz NOT NULL,
filename varchar(256),
funcname varchar(256),
linenum integer,
comment text,
domain varchar(128),
code integer,
latitude float8,
longitude float8,
created_on_server timestamptz NOT NULL,
message_id integer, (FOREIGN KEY)
app_id integer NOT NULL, (FOREIGN KEY)
result integer
);
CREATE INDEX client_log_code_idx ON client_log USING btree (code);
CREATE INDEX client_log_created_idx ON client_log USING btree (created);
CREATE INDEX clients_clientlog_app_id ON client_log USING btree (app_id);
CREATE INDEX clients_clientlog_client_id ON client_log USING btree (client_id);
CREATE UNIQUE INDEX clients_clientlog_logid_client_id_key ON client_log USING btree (logid, client_id);
CREATE INDEX clients_clientlog_message_id ON client_log USING btree (message_id);
및 예 쿼리
SELECT
client_log.comment,
COUNT(client_log.comment) AS count
FROM
client_log
WHERE
client_log.app_id = 33 AND
client_log.code = 3 AND
client_log.client_id IN (SELECT client.id FROM client WHERE
client.app_id = 33 AND
client."replaced_id" IS NULL)
GROUP BY client_log.comment ORDER BY count DESC;
을 client_log_code_idx은 위의 쿼리에 필요한 인덱스입니다. client_log_created_idx 색인이 필요한 다른 검색어가 있습니다.
그리고 쿼리 계획 : 일반적으로Sort (cost=2844.72..2844.75 rows=11 width=242) (actual time=4684.113..4684.180 rows=70 loops=1)
Sort Key: (count(client_log.comment))
Sort Method: quicksort Memory: 32kB
-> HashAggregate (cost=2844.42..2844.53 rows=11 width=242) (actual time=4683.830..4683.907 rows=70 loops=1)
-> Hash Semi Join (cost=1358.52..2844.32 rows=20 width=242) (actual time=303.515..4681.211 rows=1202 loops=1)
Hash Cond: (client_log.client_id = client.id)
-> Bitmap Heap Scan on client_log (cost=1108.02..2592.57 rows=387 width=246) (actual time=113.599..4607.568 rows=6962 loops=1)
Recheck Cond: ((app_id = 33) AND (code = 3))
-> BitmapAnd (cost=1108.02..1108.02 rows=387 width=0) (actual time=104.955..104.955 rows=0 loops=1)
-> Bitmap Index Scan on clients_clientlog_app_id (cost=0.00..469.96 rows=25271 width=0) (actual time=58.315..58.315 rows=40662 loops=1)
Index Cond: (app_id = 33)
-> Bitmap Index Scan on client_log_code_idx (cost=0.00..637.61 rows=34291 width=0) (actual time=45.093..45.093 rows=36310 loops=1)
Index Cond: (code = 3)
-> Hash (cost=248.06..248.06 rows=196 width=4) (actual time=61.069..61.069 rows=105 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 4kB
-> Bitmap Heap Scan on client (cost=10.95..248.06 rows=196 width=4) (actual time=27.843..60.867 rows=105 loops=1)
Recheck Cond: (app_id = 33)
Filter: (replaced_id IS NULL)
Rows Removed by Filter: 271
-> Bitmap Index Scan on clients_client_app_id (cost=0.00..10.90 rows=349 width=0) (actual time=15.144..15.144 rows=380 loops=1)
Index Cond: (app_id = 33)
Total runtime: 4684.843 ms
추가 정보없이 답을 얻을 수 없습니다. 쿼리는 어떻게 생겼습니까? 쿼리 실행 계획은 무엇입니까 (http://wiki.postgresql.org/wiki/SlowQueryQuestions 참조). 그러나 일반적으로 다른 인덱스를 시도해 보는 것이 좋습니다 (삽입 속도는 불필요한 모든 인덱스를 삭제하십시오). 그런 다음 분할을 시도하십시오. –
'id serial'은 아마 기본 키로 사용됩니다 : try - >>'id (big) serial NOT NULL PRIMARY KEY' – wildplasser
좋은 지적입니다. 나는 그것을 변경했다 :'ALTER TABLE client_log DROP COLUMN id;''ALTER TABLE client_log ADD COLUMN id bigserial NOT NULL PRIMARY KEY;'(_id_는 다른 곳에서는 사용되지 않았다.) – kev