2012-12-03 2 views
1

나는 행 ~ 160,000,000 많이 들어있는 PostgreSQL 데이터베이스 있습니다. 데이터베이스는 기본적으로 네트워크 로그 집합입니다. 타임 스탬프 인 time이라는 열이 있습니다. 기본적으로 모든 고유 한 시간마다 네트워크의 각 시스템에 대한 로그가 있습니다. 따라서 동일한 타임 스탬프가있는 여러 행이 있습니다. 즉PostgreSQL의 인덱스 성능 문제

time ip    value 
2:00 192.168.1.1 5 
2:00 192.168.1.2 4 
2:00 192.168.1.3 5 
3:00 192.168.1.1 3 
3:00 192.168.1.2 5 
3:00 192.168.1.3 2 
etc  etc 

이제이 데이터베이스에 대한 색인을 항상 관련 검색어로 사용하는 입력란으로 만들었습니다. 전체 데이터베이스를 스캔하는 데 인해 쿼리에 모든 쿼리가 약 2 분 소요 인덱스를 사용하지 않고

i.e. select * from networklogs where time = '2:00' and value = 5 

. 내 쿼리가 일치하는 시간을 포함하는 데이터의 하위 집합을 찾은 다음 여기에서 다른 값을 기준으로 필터링하므로 쿼리가 훨씬 빨라지기를 기대하는 인덱스를 만들었습니다. 이 이상하다

쿼리 지금이 더 걸릴 것으로 보인다 그러나

... 때문에 pgAdmin에 쿼리가 시간 인덱스를 사용하는 것으로, 시간 지수는 총 ~ 80 개 항목에 대한 데이터를 좁히는 것을 설명 160,000,000이고 쿼리 필터는이 데이터를 1,700 개 항목으로 좁 힙니다. 이 설명은 17ms 걸리지 만 쿼리를 실행하면 3 분이 걸립니다.

이것은 160,000,000 항목에 두 개의 키워드와 일치하는 검색보다 더 빨리해야합니다!

이 pgAdmin 쿼리를 수행 할 때 실제로 사용 않는 시간 인덱스를 사용하여 같이 쿼리를 설명에도 불구하고, 난 궁금하네요 빨리하지 왜 작동하지 수 있습니까?

는 사람이 어떤 아이디어 나 제안 사항이 있습니까?

감사합니다, 제임스는

는 업데이트 :

explain analyze select latitude,longitude from networklogs where value = 5 and time = '2:00' 

결과는 다음과 같습니다 :

"Bitmap Heap Scan on networklogs (cost=13178.17..1488620.94 rows=848 width=19) (actual time=3507.923..278760.509 rows=33 loops=1)" 
" Recheck Cond: (time = '2:00'::timestamp without time zone)" 
" Rows Removed by Index Recheck: 38302021" 
" Filter: (value = 5)" 
" Rows Removed by Filter: 882873" 
" -> Bitmap Index Scan on timeindex (cost=0.00..13177.95 rows=530111 width=0) (actual time=695.771..695.771 rows=882906 loops=1)" 
"  Index Cond: (time = '2:00'::timestamp without time zone)" 
"Total runtime: 278764.148 ms" 
+0

VACUUM ANALYZE를 시도하십시오. – randomguy

+0

감사합니다. 지금 사용해보세요! –

+0

특정 시점의 이전 데이터를 백업하고 최근 데이터를 x만큼만 유지할 수있는 권한이 있습니까? – bonCodigo

답변

3

, 나는 그들에 여러 인덱스를 만들 수 권합니다. , 실제 상황에서, 데이터베이스는 시간에 인덱스를 가지고 있기 때문에이 조건에 맞는 행을 알 수있다 그러나 그것은 인덱스에 의해 주어진 모든 다른 장소에서 그들을 가져올하고 차 상태를 확인해야하므로.

CREATE INDEX time_and_value ON networklogs (time, value); 

이 인덱스를 사용하여 데이터베이스가 다른 상태를 확인하기 위해 데이터를 가져올 필요가 없습니다, 그것은 단순히 이미 검색 기준과 일치 알고있는 데이터를 가져옵니다. 순서는 물론 중요합니다.

위도와 경도 데이터를 사용하고 있습니다. 아마도 point 유형을 사용하면 좋을 것이므로 기본값으로 Postgres와 함께 제공되는 geometric operators을 모두 사용할 수 있습니다.이러한 종류의 데이터도 색인화 할 수 있습니다.

+0

EXPLAIN 출력을 보면 'time' 인덱스는 882,906 행을 0.7 초 내에 찾습니다. 그런 다음 99.996 %의 데이터 만 삭제하기 위해 데이터베이스에 27.1 초가 걸려 모든 행을 가져옵니다 (아마도 많은 디스크 검색) (http://stackoverflow.com/a/13236089/1026671). 두 컬럼 모두에 대한 색인이 필요합니다. – willglynn

+0

죄송합니다. 27 초가 아니라 278 초 (3.16ms/행)입니다. 나에게 무작위로 읽는 것처럼 들린다. – willglynn

+0

답변 해 주셔서 감사합니다. 그래서 나는 여러개의 인덱스를 생성 할 필요가있다. 이것이 가능한가? 예를 들어, 실제 데이터베이스에는 위의 예제보다 더 많은 열이 있습니다. 시간 및 값, 시간 및 플래그, 시간 및 노드와 같은 일부 인덱스가 필요합니다. –

2

PostgreSQL을이 방법을 검토 EXPLAIN and EXPLAIN ANALYZE을 가지고 난 다음 명령에 ANALYZE EXPLAIN 실행 한 쿼리가 실행됩니다. PG Admin은 EXPLAIN을 사용하여 쿼리 실행 방법을 알려줍니다. EXPLAIN ANALYZE를 사용하면 더 정확한 결과를 얻을 수 있습니다. EXPLAIN ANALYZE는 실제로 쿼리를 실행하고 실제 실행에서 통계를 생성합니다. 예상대로 인덱스를 사용하고 있더라도 시간이 소비 된 곳을 적어도 알 수 있습니다. 이 당신에 대한 검색 수를 수행하고자하는 매개 변수는 주로 경우

+0

고마워, 지금 해봐! –

+0

설명 분석을 실행했지만, 이것이 의미하는 바를 제게 설명해주십시오. "비트 맵 힙 스캔 (비용 = 13178.17.1488620.94 행 = 848 너비 = 19) (실제 시간 = 3507.923..278760.509 행 = 33 루프 = 1) ""시간과 수행 된 행동 측면에서? 이것은 출력 결과의 첫 줄입니다. –

+0

전체 출력이 원래 게시물에 업데이트로 추가되었습니다. –