보통 특정 테이블의 row count 수를 알고 싶을 때 

SELECT count(*) FROM {schema}.{tableName};

의 쿼리를 사용했을 것이다. 

 

본론만 말하자면 

SELECT schemaname, relname, n_live_tup
FROM pg_stat_user_tables
-- where schemaname = '{schemaname}'
ORDER BY n_live_tup DESC;

이 쿼리를 사용하면 거의 1~2초만에 결과를 얻을 수 있다. 

where문은 해당하는 스키마의 테이블들만 볼 수 있는 쿼리고 없애면 전체 데이터베이스의 테이블들을 볼 수 있다. 

 

postgresql count 속도는 왜 느린가?

postgresql의 어떤 속성인지는 모르겠으나 count(*) 속도가 정말 정말 정말 상상도 할 수 없을 만큼 느리다.

왜 느린 거지? vacuum도 돌리고 dead tuple도 지우면서 관리한다고 생각했는데도 count(*) 쿼리 속도는 항상 느리다 

 

나는 보통 ETL 작업을 하기 때문에 DQ(데이터 품질) 검사를 할 때 우선적으로 하는 일은 ETL 적재한 테이블의 컬럼수를 확인하는 것이다. 

 

ETL 할 테이블이 수십 개가 되는데 이걸 하나하나 count Rows를 할 수는 없다. 시간 낭비에 심지어 쿼리 돌아가는 속도도 느리고 기분 탓인지는 모르겠지만 서버에 안 좋을 것 같은 기분이 든다...... 

 

https://postgresql.kr/docs/9.3/monitoring-stats.html

 

통계 수집기

PostgreSQL 통계 수집기 statistics collector는 서버 운영 상태에 대한 정보를 수집하거나 보고하기 위한 작업을 하는 백그라운드 시스템이다. 현재, 이 수집기는 테이블이나 인덱스의 디스크 블록 단위

postgresql.kr

postgresql 한글 문서다 

다른 DB는 잘 모르겠지만 postgresql은 통계 수집기라는 백그라운드 시스템이 있다. pg_ 어쩌고 라는 곳에서 view들을 만들어 사용자들이 쉽게 모니터링을 할 수 있게 만든 것임. 

 

이런 통계 수집에 대한 커스텀은 postgresql.conf 파일에서 할 수 있다고 한다. 자세한 것은 문서 참고! 

나는 vacuum에 대한 작업들을 커스텀 했던 기억이 있다. 

 

pg_stat_user_tables을 이용한 Explain.
count(*)로 진행한 쿼리 Explain.

실제로 약 2억 건의 count(*) 쿼리는 8분 정도가 걸렸다 

애초에 접근하는 테이블 자체가 다르기 때문에 속도가 현저하게 다른 것 같다. 

실제 현업 서비스에서는 count(*)를 사용하는 경우는 별로 없을 것이다 내가 배우고 경험하기로는 사용자 서비스 서버에 count(*)를 때려 박으면 과부화가...... 메모리가....... 어마무시하게 터진다고 알고 있음 

 

하지만 나같이 전체 테이블의 row 수를 알고 싶은 경우도 있으니 괜히 count(*) 써서 서버 비용 높이지 말고 pg에서 제공하는 view를 애용하자!