count(1) vs count(*) – any difference?
A while ago when I started my first job in LA, I was using MSSQL. I was told to never use count(*), and rather to use count(1). Several people insisted this performs better than count(*), and since I really didn’t care to argue or look into it, I just started doing it.
Fast forward to today, where I am still writing count(1), but on MySQL. I’m at a different company now, but working with a lot of the same people. The person who used to be my boss is now my equal, and while mytop was running, noticed the count(1) and was happy to see it. Which reminded me to wonder – does it even matter?
(Using a table called questions, 130K rows)
EXPLAIN SELECT count( 1 )
FROM questions;
Says it’s a simple select, and it’s using the index. Fantastic.
explain select count(*) from questions;
Same result as above. I’ve always assumed that the database engine would map count(*) as a special exception to just count all the rows, rather than actually looking at every field in the table. Since Oracle makes this (simple) calculation, I would assume the MySQL developers did as well.
If I am wrong, please let me know. If anyone knows about MSSQLs execution plans in the different versions, please leave me a comment with your results.
4 Responses to count(1) vs count(*) – any difference?
Leave a Reply Cancel reply
Recent Comments
- pratibha on MySQL Triggers Tutorial
- pratibha on MySQL Triggers Tutorial
- MySQL Tutorials on MySQL Triggers Tutorial
- jon on The Lack of Flexibility of Stored Procedures in MySQL
- Nithya on The Lack of Flexibility of Stored Procedures in MySQL
- vietnam travel guide on MySQL Triggers Tutorial
- Phil Freo on Making Better Use of your .ackrc file
- PHP Examples on MySQL Triggers Tutorial
- jon on Drizzle Differences from MySQL
- Will on Drizzle Differences from MySQL
Recent Posts
- Vim: Use !make: to avoid auto jumping to files
- Weird Disutils Error When Running Python Scripts within MacVim
- Installing vim-ipython with MacVim
- Applescripting A Remote X-Windows Session for Virt-Manager
- Drizzle Differences from MySQL
- Great Article by the Varnish Architect
- Making Better Use of your .ackrc file
- Nginx pub/sub module
- Coffeescript, Bootstrap, and Less are amazing
- Splitmytab ready for the public!
Categories
- ack (1)
- amazon (1)
- answerbag (6)
- apache (9)
- apple (9)
- awk (2)
- bbedit (2)
- bootstrap (1)
- c++ (3)
- chrome (2)
- cluster (1)
- cocoa (1)
- coffeescript (2)
- collective intelligence (1)
- css (1)
- curl (3)
- db2 (1)
- demand media (1)
- drizzle (1)
- ebay (1)
- eclipse (4)
- erlang (13)
- facebook (1)
- fortran (1)
- gen_server (1)
- git (5)
- google (4)
- haddad (1)
- hdf5 (1)
- html (1)
- innodb (1)
- itunes (1)
- java (2)
- jester (2)
- kvm (2)
- launchbar (1)
- leex (1)
- less (1)
- letsgetnuts.com (1)
- libvirt (1)
- links (6)
- linux (28)
- lucene (1)
- mac (16)
- memcached (1)
- misconception (1)
- mobile (1)
- mono (1)
- mssql (1)
- munin (1)
- mysql (34)
- nginx (1)
- numpy (1)
- oracle (1)
- php (23)
- puppet (4)
- pyparsing (1)
- pytables (1)
- python (13)
- q&a (1)
- quicksilver (1)
- rant (6)
- readynas (1)
- redis (2)
- regex (1)
- replication (1)
- search (1)
- shitty code (1)
- solr (3)
- spaces (1)
- splitmytab (2)
- sshfs (1)
- stored procedure (1)
- svn (5)
- textmate (2)
- tips (25)
- tornado (1)
- trac (1)
- tutorial (4)
- ubuntu (3)
- Uncategorized (5)
- unix (1)
- vim (6)
- virtual box (6)
- vmware (1)
- weird (3)
- wikipedia (1)
- windows (1)
- xcode (1)








They are treated essentially the same. You can see below that mysql internally rewrites count(*) to count(0).
mysql> explain extended select count(*) from foo;
+—-+————-+——-+——+—————+——+———+——+——+——————————+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+—-+————-+——-+——+—————+——+———+——+——+——————————+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away |
+—-+————-+——-+——+—————+——+———+——+——+——————————+
1 row in set, 1 warning (0.03 sec)
mysql> show warnings;
+——-+——+————————————————-+
| Level | Code | Message |
+——-+——+————————————————-+
| Note | 1003 | select count(0) AS `count(*)` from `test`.`foo` |
+——-+——+————————————————-+
1 row in set (0.00 sec)
mysql> explain extended select count(1) from foo;
+—-+————-+——-+——+—————+——+———+——+——+——————————+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+—-+————-+——-+——+—————+——+———+——+——+——————————+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away |
+—-+————-+——-+——+—————+——+———+——+——+——————————+
1 row in set, 1 warning (0.00 sec)
mysql> show warnings;
+——-+——+————————————————-+
| Level | Code | Message |
+——-+——+————————————————-+
| Note | 1003 | select count(1) AS `count(1)` from `test`.`foo` |
+——-+——+————————————————-+
1 row in set (0.00 sec)
Also, on MyISAM an internal row count is maintained which is used for COUNT……
COUNT(*) is converted to COUNT(1) within the parser, therefore very early in the query execution sequence.
Hi!
They are identical in MSSQL as well. There is, however, a big difference in T-SQL/MSSQL between the performance of EXISTS() and SELECT COUNT(*) to determine existence…
Cheers,
Jay