PostgreSQL : COUNT (*)는 색인이 아닌 순차적 스캔을 사용합니다.


12

PostgreSQL이 COUNT(*)쿼리를 위해 테이블을 순차적으로 스캔하는 이유는 무엇 입니까? 매우 작고 인덱스 된 기본 키가 있습니까?

답변:


16

공식 위키 페이지는 그에 대한 답변을 제공합니다 :

[...] 이것이 느린 이유는 PostgreSQL의 MVCC 구현과 관련이 있습니다. 여러 트랜잭션이 서로 다른 상태의 데이터를 볼 수 있다는 사실은 "COUNT (*)"가 전체 테이블에서 데이터를 요약 할 수있는 직접적인 방법이 없다는 것을 의미합니다. PostgreSQL은 어떤 의미에서든 모든 행을 통과해야합니다. 이는 일반적으로 테이블의 모든 행에 대한 정보를 순차적으로 읽는 결과를 낳습니다. [...]

또한 ANALYZE 를 사용하여 쿼리 플래너에 대한 정보를 다시 작성할 수 있습니다.

사용하면 더 나은 성능을 얻을 수 COUNT(an uniquly indexed field)있지만 이것이 매우 큰 경우 seq 스캔이 유일한 방법입니다.

매우 빠른 숫자가 필요하고 스키마 쿼리를 두려워하지 않는 경우 다음을 수행 할 수 있습니다.

SELECT reltuples FROM pg_class WHERE oid = 'your_table'::regclass

그러나이 값은 테이블에서 "추정 된"(정확한 경우도 있지만) 튜플 수이므로이 값에 의존하지 마십시오.


나는 이것이 옳지 않다고 생각합니다. COUNT(pk)성능을 향상시킬 수 있는 곳 은 읽지 않았습니다 . 나는 그것이 항상 seq-scan을 할 것이라고 생각한다
vol7ron

1
where 절이 없으면 seq 스캔이 수행됩니다. postgresql CAN은 인덱스를 사용하는 where 절을 충분히 선택했지만 테이블로 돌아가보고하는 튜플의 가시성을 확인합니다.
Scott Marlowe

기억하기 쉬운 예상 행 수를 얻는 또 다른 방법은 EXPLAIN SELECT * from your_table;입니다. 쿼리가 실행되지 않습니다. 출력에는 rows=…예상 행 수가 포함 됩니다.
Sven Marnach
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.