Select count(*) VS. Select count(column_name)

Thomas Darimont

Erfahrenes Mitglied
Hallo!

select count(*) vs. select count(column)
Weis zufaellig jemand ob es Performancemaessig einen Unterschied macht,
ob man select count(*) oder select count(column_name) verwendet um die
Anzahl der Zeilen einer Tabelle zu ermitteln?

Das es einen sematischen Unterschied gibt weis ich...:
Beispiel:

Code:
  mysql> SELECT * FROM selectCountPerfTest limit 15;
  +----+-------------+-------------+-------------+-------------+-------------+
  | id | column1	 | column2	 | column3	 | column4	 | column5	 |
  +----+-------------+-------------+-------------+-------------+-------------+
  |  1 | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! |
  |  2 | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! |
  |  3 | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! |
  |  4 | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! |
  |  5 | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! |
  |  6 | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! |
  |  7 | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! |
  |  8 | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! |
  |  9 | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! |
  | 10 | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! |
  | 11 | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! |
  | 12 | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! |
  | 13 | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! |
  | 14 | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! |
  | 15 | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! | Hallo Welt! |
  +----+-------------+-------------+-------------+-------------+-------------+
  15 rows in set (0.28 sec)

Code:
  mysql> select count(*) from selectCountPerfTest;
  +----------+
  | count(*) |
  +----------+
  |  1010717 |
  +----------+
  1 row in set (3.25 sec)
Wie ihr seht hat meine Testtabelle 1010717 Zeilen mit dem oben genannten Inhalt...
mann dass hat vielleicht lange gedauert die alle einzutippen...
Wie ihr seht braucht das Statement 3.25 Sekunden. (Habs ein paar mal gemacht,
3.25 war der Mittelwert)

Code:
  mysql> select count(column1) from selectCountPerfTest;
  +----------------+
  | count(column1) |
  +----------------+
  |		1010717 |
  +----------------+
  1 row in set (3.25 sec)
Wie man sieht, ist das Statement im Mittel genauso schnell...

Wenn ich nun, aber folgendes mache:
Code:
  mysql> update selectCountPerfTest set column1=null where id = 786738;
  Query OK, 1 row affected (0.19 sec)
  Rows matched: 1  Changed: 1  Warnings: 0

dann erhalte ich einmal das:
Code:
  mysql> select count(*) from selectCountPerfTest;
  +----------+
  | count(*) |
  +----------+
  |  1010717 |
  +----------+
  1 row in set (3.34 sec)
und einmal dies:
Code:
  mysql> select count(column1) from selectCountPerfTest;
  +----------------+
  | count(column1) |
  +----------------+
  |		1010716 |
  +----------------+
  1 row in set (3.34 sec)
Was ja auch klar ist, da count(...) NULL Werte nicht mitzaehlt.

Getestet unter MySQL 5.0, Win XP, 512 MB Ram, 1,8 GHz Pentium-M

Gruss Tom
 
Hier Ergebnisse mit MySQL 4.1.10a unter Win2k, Athlon XP 2500+, 512MB.

Testdaten:
Code:
mysql> describe counttest;
+-------+------------------+------+-----+---------+----------------+
| Field | Type             | Null | Key | Default | Extra          |
+-------+------------------+------+-----+---------+----------------+
| id    | int(11) unsigned |      | PRI | NULL    | auto_increment |
| field | char(255)        | YES  |     | NULL    |                |
+-------+------------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

mysql> select * from counttest order by rand() limit 15;
+-------+------------+
| id    | field      |
+-------+------------+
| 35302 | aString 70 |
| 20512 | aString 84 |
| 70984 | aString 23 |
|  1468 | aString 7  |
| 34472 | aString 73 |
| 74277 | aString 21 |
| 78049 | aString 36 |
| 10870 | aString 70 |
| 70547 | aString 46 |
| 75747 | aString 33 |
| 28172 | aString 68 |
| 51745 | aString 51 |
| 74066 | aString 28 |
| 24015 | aString 93 |
| 63680 | aString 99 |
+-------+------------+
15 rows in set (3.66 sec)

mysql> select count(*) from counttest;
+----------+
| count(*) |
+----------+
|    80812 |
+----------+
1 row in set (0.00 sec)
Die Abfragen, jeweils aus 14 Versuchen:
Code:
mysql> select sql_no_cache count(*) from counttest;
Mittelwert         : 1,16
Standardabweichung : 0,06
Minimum            : 1,09
Maximum            : 1,27

mysql> select sql_no_cache count(id) from counttest;
Mittelwert         : 1,22
Standardabweichung : 0,23
Minimum            : 1,09
Maximum            : 1,98

mysql> select sql_no_cache count(field) from counttest;
Mittelwert         : 1,17
Standardabweichung : 0,04
Minimum            : 1,09
Maximum            : 1,24
Die vom Handbuch versprochene Optimierung von count(*) ist scheinbar ohne Cache nicht so ausschlaggebend, wie das Handbuch vermuten lässt.

Arbeitet man jedoch mit Chaching, so werden die Vorteile von count(*) deutlich:
Code:
mysql> select count(*) from counttest;
+----------+
| count(*) |
+----------+
|    80812 |
+----------+
1 row in set (0.00 sec)

mysql> select count(*) from counttest;
+----------+
| count(*) |
+----------+
|    80812 |
+----------+
1 row in set (0.00 sec)

mysql> select count(id) from counttest;
+-----------+
| count(id) |
+-----------+
|     80812 |
+-----------+
1 row in set (1.11 sec)

mysql> select count(id) from counttest;
+-----------+
| count(id) |
+-----------+
|     80812 |
+-----------+
1 row in set (0.00 sec)

mysql> select count(field) from counttest;
+--------------+
| count(field) |
+--------------+
|        80812 |
+--------------+
1 row in set (1.22 sec)

mysql> select count(field) from counttest;
+--------------+
| count(field) |
+--------------+
|        80812 |
+--------------+
1 row in set (0.00 sec)
Dargestellt sind jeweils nur der erste und der zweite Aufruf der Abfragen. Der jeweils dritte, vierte usw. ist dann identisch mit dem zweiten.

Gruß hpvw
 

Neue Beiträge

Zurück