나는 문서 에서 count(*)
와 의 차이점을 보았습니다 count(pk)
. 나는 존재에 대해 모르고 count(pk)
(어디서나 pk
) 사용하고 있었다 .SERIAL PRIMARY KEY
count(*)
내 질문은 Postgres의 내부 최적화에 관한 것입니다. a SERIAL PRIMARY KEY
가 모든 행에 존재하고 거짓이 아니며 행을 계산하거나 각 행에 대해 중복 술어 검사를 수행 한다는 것을 선택하는 것이 똑똑 합니까? 나는 이것이 무의미한 최적화 일 것임에 동의하지만 나는 단지 궁금합니다.
나는의 출력에서보고했다 EXPLAIN
및 EXPLAIN VERBOSE
를 들어 count(*)
, count(id)
하고 count(id > 50)
있는지 확인하기 위해 EXPLAIN
출력의 조건을 확인 언급했다. 그렇지 않습니다.
답변
나는 지난 수년 동안 다양한 버전의 내 반복 시험에서 일관된 결과를 얻었다 :
count(*)
있습니다 약간 보다 더 빨리 count(pk)
. 또한 짧고 대부분의 경우 테스트 대상에 더 적합합니다. 행의 존재.
에 관하여:
Postgres는 a
SERIAL PRIMARY KEY
가 모든 행에 존재하고 결코 거짓이 될 수 없다는 것을 알기에 충분히 똑똑합니까?
유일하게 관련된 것은 NOT NULL
제약입니다. 는 PRIMARY KEY
것입니다 NOT NULL
자동, serial
또는 never false
질문에 직교한다.
로 count(col)
, 경우 PostgreSQL의 스마트하고 열이인지 시스템 카탈로그를 확인하려고했다 NOT NULL
과 동등한으로 폴백을 count(*)
, 당신은 여전히 하나 더 룩업 시스템 테이블에보다이있을 것이다 count(*)
.
에 관해서는 EXPLAIN
출력이 있습니다 힌트 :
EXPLAIN SELECT count(*) FROM ...
Aggregate (cost=4963.38..4963.43 rows=1 width=0) ...
EXPLAIN SELECT count(pk) FROM ...
Aggregate (cost=4963.38..4963.43 rows=1 width=4) ...
의미 count(col)
는 로 정의되어 있어도 로 변환 되지 않습니다 .count(*)
NOT NULL