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
- Anil on MySQL Triggers Tutorial
- Ashish on MySQL Triggers Tutorial
- David on iCal Agenda
- jon on IP address geolocation SQL database
- pim on IP address geolocation SQL database
- jnns on Redis Wildcard Delete
- K.C. Murphy on iCal Agenda
- BA on Experts Exchange should be removed from Google search results
- Andrew on Executing multiple curl requests in parallel with PHP and curl_multi_exec
- Stu on Executing multiple curl requests in parallel with PHP and curl_multi_exec
Recent Posts
- New Project: Jester
- Open New Terminal Tip
- Installing MySQLdb on MacOS Lion
- Headless VM Server Using Ubuntu 11.10
- Get rid of Facebook’s Awful Ticker
- Api Tester now hosted on Github
- Trac .11 jQuery bug
- Multiple Filetypes in Vim
- Git Tip: Setting Up Your Remote Server
- Install issue pymongo on OSX (setuptools out of date)
Categories
- amazon (1)
- answerbag (6)
- apache (9)
- apple (8)
- awk (2)
- bbedit (2)
- c++ (3)
- chrome (2)
- cluster (1)
- cocoa (1)
- collective intelligence (1)
- curl (3)
- db2 (1)
- demand media (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 (1)
- kvm (1)
- launchbar (1)
- leex (1)
- letsgetnuts.com (1)
- libvirt (1)
- links (6)
- linux (27)
- lucene (1)
- mac (16)
- memcached (1)
- misconception (1)
- mobile (1)
- mono (1)
- mssql (1)
- munin (1)
- mysql (31)
- numpy (1)
- oracle (1)
- php (23)
- puppet (4)
- pyparsing (1)
- pytables (1)
- python (11)
- q&a (1)
- quicksilver (1)
- rant (6)
- readynas (1)
- redis (2)
- regex (1)
- replication (1)
- search (1)
- shitty code (1)
- solr (3)
- spaces (1)
- sshfs (1)
- stored procedure (1)
- svn (5)
- textmate (2)
- tips (22)
- trac (1)
- tutorial (4)
- ubuntu (3)
- Uncategorized (4)
- unix (1)
- vim (3)
- 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