Vi en la documentación la diferencia entre count(*)y count(pk). Había estado usando count(pk)(donde pkestá a SERIAL PRIMARY KEY) sin saber sobre la existencia de count(*).
Mi pregunta es sobre las optimizaciones internas de Postgres. ¿Es lo suficientemente inteligente como para darse cuenta de que SERIAL PRIMARY KEYa existirá en cada fila y nunca será falso y solo contará filas o hará verificaciones redundantes de predicados para cada fila? Estoy de acuerdo en que esta es probablemente una optimización demasiado inútil, pero tengo curiosidad.
Eché un vistazo a la salida de EXPLAINy EXPLAIN VERBOSEpara count(*), count(id)y count(id > 50)para ver si EXPLAINmencionó verificar los predicados en su salida. No lo hace.

NOT NULLcolumna, la diferencia es grande si tienes muchas filas. En nuestro caso con millones de filas,COUNT(*)es 3 veces más rápido. (Postgres 9.4)