No. This appears to be a persistent misconception, based on a confusion between the syntax
SELECT * FROM ...
and
SELECT COUNT(*) FROM ...
In the first case, *
refers to all columns, and returning those certainly requires more resources than returning a single column. In the second case, COUNT(*)
is simply shorthand for "count all rows". The mistaken belief is that COUNT(*)
somehow instructs the database engine to examine all columns in all rows, whereas COUNT(<pk_field>)
would only have to look at one column.
There are a number of other comments on SO here that reference the SQL-92 standard, which explicitly states that COUNT(*)
should just refer to the cardinality of the table, so, at least in theory, database engines should be able to recognize and optimize that.
As far as I can tell, in both cases, most database engines (Postgres, Oracle, MySQL InnoDB) will just perform an index scan to count the number of rows. If you specify the PK, then that index will be used; if you just use COUNT(*)
, then the query planner will pick an index which spans the entire table*, but the performance should be identical.
The only exception to this that I can find is MySQL with MyISAM tables -- those tables cache the number of rows, so COUNT(*)
is very fast. However, the query planner also recognizes COUNT(<field>)
, where <field>
is any non-null column, as a request for the full table size, and uses the cache in that case as well. (source) So again, no difference in performance.
* Theoretically, if you had no such indexes, then COUNT(*)
would be very slow, but in that case, COUNT(<pk>)
would be impossible by definition