vo vseobecnosti by vyhodnejsim zapisom mal byt 'count(primary_key)' ... * totiz znamena vsetky stlpce, co moze znamenat, ze db server natiahne do pamate cele riadky a az potom spusti agregatnu funkciu. (samozrejme predpokladam ze primary_key je int/bigint)
to, ze count sa malokedy pouziva na celu tabulku ale v suvislosti s inymi parametrami (ci uz WHERE alebo GROUP BY napriklad) uz bolo spomenute :-))
Bylo by naivní myslet si, že COUNT(*) funguje tak, že databáze do paměti natáhne celou tabulku a následně spočte řádky. Takovéto konstrukce jsou samozřejmě optimalizované. Záleží ale na konkrétní databázi, co je rychlejší a co pomalejší - jak už jsem psal, tak COUNT(id) je pokud vím rychlejší než COUNT(*) např. ve starších verzích Oracle, v jiných databázích to může být zase naopak. MySQL je optimalizované na COUNT(*) (jak ukazují třeba příklady v MySQL dokumentaci), ale COUNT(id) mu problémy dělat jistě taky nebude.
Ono také jde o to, co COUNT přesně počítá, jak databáze zachází s transakcemi a podobně, že. Například důvod, proč Firebirdu nestačí ke spočítání řádků scan nějakého indexu je verzování řádků. Důvodem, proč ke spočítání COUNT(sloupec) nestačí scan indexu i bez verzování a třeba i bez transakcí je zase ten, že COUNT(sloupec) musí ignorovat NULL hodnoty. Takže COUNT(id) je principielně spíš o dost náročnější než COUNT(*), alespoň na disk fetche a u tabulek s hodně sloupci.