REINDEX는 위험한가요?


17

COUNT(*)기본 키가있는 150,000 개의 행이있는 테이블을 시도했습니다 . 그것은 약 5 분 도구이므로 이것이 색인 문제라는 것을 알았습니다.

PostgreSQL 매뉴얼 인용 :

REINDEX는 인덱스 내용이 처음부터 다시 작성된다는 점에서 인덱스 삭제 및 재 작성과 유사합니다. 그러나 잠금 고려 사항은 다소 다릅니다. REINDEX는 인덱스의 상위 테이블에 대한 쓰기를 잠그지 만 읽기는 잠급니다. 또한 처리중인 특정 인덱스에 대해 독점 잠금을 수행하여 해당 인덱스를 사용하려는 읽기를 차단합니다 (...) 후속 CREATE INDEX는 쓰기를 잠급니다. 그러나 읽기는하지 않습니다. 인덱스가 없으므로 읽기가 인덱스를 사용하려고 시도하지 않습니다. 즉, 블로킹은 없지만 읽기는 비싼 순차적 스캔으로 강제 될 수 있습니다.

자신의 경험을 통해 다음과 같이 말할 수 있습니다.

  • REINDEXING위험? 데이터 일관성에 해를 끼칠 수 있습니까?
  • 시간이 많이 걸리나요?
  • 내 시나리오에 대한 가능한 솔루션입니까?

최신 정보:

우리에게 도움이 된 해결책은 다른 이름으로 동일한 색인을 다시 만든 다음 이전 색인을 삭제하는 것이 었습니다.

인덱스 생성이 매우 빠르며 인덱스 크기를 650MB에서 8MB로 줄였습니다. COUNT(*)with를 사용하는 between데 3 초 밖에 걸리지 않습니다.

답변:


15

재색 인화는 위험하지 않으며 데이터 일관성을 해칠 수 없습니다. 그러나 시간이 중요한 쓰기가있는 경우 테이블이 잠겨 있고 DML이 중단되면 데이터가 손실 될 수 있습니다.

재 인덱싱에는 많은 시간이 걸리지 않지만 일반적으로 전체 테이블을 읽고 인덱스 필드를 정렬하고 새 인덱스를 작성해야합니다. 시간 COUNT(*)이 걸리면 5 분 이상이 소요될 수 있습니다.

이것이 인덱싱 문제 일 가능성은 낮습니다. COUNT(*)인덱스를 읽을 수없는 테이블 스캔을 사용해야합니다. 나는 당신이 어떤 종류의 IO 문제를 가질 것으로 기대합니다.

사용해보십시오 COUNT(1)또는 COUNT(pk_field)인덱스를 사용할 수있다.

Unix 또는 Linux 플랫폼에서 실행중인 경우로 디스크 활동을 모니터링 할 수 있습니다 sar. 또한 디스크 속도에 문제가있어 IO 속도를 크게 줄일 수 있습니다.

큰 객체가있는 테이블은 IO를 크게 증가시켜 COUNT (*)에 대한 레코드를 구성 할 수 있습니다.


2
wiki.postgresql.org에 따르면 COUNT(*), 최선의 선택은 다음과 같습니다.If you are using count(*), the database is free to use any column to count, which means it can pick the smallest covering index to scan (note that this is why count(*) is much better than count(some_field), as long as you don't care if null values of some_field are counted). Since indexes often fit entirely in memory, this means count(*) is often very fast.
orange80

1

나는 당신에게 가장 좋은 대답을 확신하지 못합니다. 그러나이 스레드는 몇 가지 좋은 제안을 제공하는 것 같습니다 : n http://postgresql.1045698.n5.nabble.com/count-performance-issue-td2067873.html

한 가지 메모는 TRIGGER를 구현하여 별도의 테이블에서 행 수를 유지 관리 할 수 ​​있다는 것입니다 (응용 프로그램에서 COUNT (*)를 자주 호출하는 경우).

몇 가지 응답은 최근에 충분히 진공 청소기로 청소하지 않은 데이터베이스의 증상이라고 제안합니다 (서버 또는 특히 해당 데이터베이스에 대해 자동 진공 기능이 비활성화되어 있음).

다른 제안은 다음과 같습니다.

ANALYZE tablename;
SELECT reltuple FROM pg_class WHERE relname = 'tablename';

A. Kretschmer는 다음과 같이 지적했습니다.

현재 인덱스 구현에는 현재 트랜잭션 내의 행 가시성에 대한 정보가 없습니다. 현재 트랜잭션 내에서 현재 행이 표시되는지 확인하려면 전체 데이터 테이블을 스캔해야합니다.

... 행 수준 권한에 대한 내 의견을 지원하면 성능 문제가됩니다.

검색 결과 WikiVS : MySQL vs. PostgreSQL : COUNT (*) 도 나타났습니다 .

Google : postgresql count (*) 성능 을 사용하여 찾은 다른 결과를 살펴볼 수 있습니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.