Page 1 of 1

select count(id) from my_table

Posted: 2008-01-06 16:38
by simcen
Hallo Zusammen

Ich habe eine Datenbank, mit mehreren Millionen Einträgen.
INSERT und SELECT gehen dank ImmoDB und gut ausgelegten Indizes sehr gut.
Einziges Problem: ein "SELECT COUNT(id) FROM my_table" dauert beim ersten Aufruf sehr lange.
Wie kann die die Anzahl der Zeilen effizient aus der DB holen?

Desweiteren interessiert mich, ob das Anlegen eines Indexes auf einen Primary Key sinnvoll ist oder nicht?

Danke und Gruss
Simon

Re: select count(id) from my_table

Posted: 2008-01-06 17:36
by Joe User
Lies mal die Antwort von isotopp in http://www.rootforum.org/forum/viewtopi ... 23&t=47951

Re: select count(id) from my_table

Posted: 2008-01-06 18:52
by simcen
Hab verstanden was isotopp sagen will, aber ehrlich gesagt nützt mir das auf meine Problemstellung hin nicht viel.

Hier mal ein EXPLAIN vom select count():

Code: Select all

mysql> explain select count(id) from bats40sm_cl;
+----+-------------+-------------+-------+---------------+---------+---------+------+---------+-------------+
| id | select_type | table       | type  | possible_keys | key     | key_len | ref  | rows    | Extra       |
+----+-------------+-------------+-------+---------------+---------+---------+------+---------+-------------+
|  1 | SIMPLE      | bats40sm_cl | index | NULL          | PRIMARY | 3       | NULL | 1615309 | Using index | 
+----+-------------+-------------+-------+---------------+---------+---------+------+---------+-------------+
1 row in set (0.00 sec)
Das SQL Selber:

Code: Select all

mysql> select count(id) from bats40sm_cl;        
+-----------+
| count(id) |
+-----------+
|   1505169 | 
+-----------+
1 row in set (2.57 sec)

Re: select count(id) from my_table

Posted: 2008-01-09 11:44
by isotopp
simcen wrote:

Code: Select all

mysql> explain select count(id) from bats40sm_cl;
+----+-------------+-------------+-------+---------------+---------+---------+------+---------+-------------+
| id | select_type | table       | type  | possible_keys | key     | key_len | ref  | rows    | Extra       |
+----+-------------+-------------+-------+---------------+---------+---------+------+---------+-------------+
|  1 | SIMPLE      | bats40sm_cl | index | NULL          | PRIMARY | 3       | NULL | 1615309 | Using index | 
+----+-------------+-------------+-------+---------------+---------+---------+------+---------+-------------+
1 row in set (0.00 sec)
Das ist ein Index-Scan, also wird der Index PRIMARY von vorne bis hinten durchgelesen um die Anzahl der Rows in der Tabelle zu bestimmen. Das ist auch die einzige Methode, das zu tun - wie will man sonst wissen, wie viele Rows fuer die aktuelle Transaktion sichtbar sind.

Re: select count(id) from my_table

Posted: 2008-01-09 19:40
by simcen
Wie löst man diese Situation, wenn man den Wert statistisch braucht und nicht transaktions-intern? Mutet man dem Client diese x Sekunden zu?

Re: select count(id) from my_table

Posted: 2008-01-09 19:50
by Joe User
Wenn die IDs lückenlos vergeben sind, würde das Abfragen der höchsten ID genügen, andernfalls geht es meines Wissens nach nicht schneller.

Re: select count(id) from my_table

Posted: 2008-01-09 20:48
by simcen
Was ist z.B. mit folgendem:

Code: Select all

mysql> show table status from wasi61a like 'bats40sm_cl'G;
*************************** 1. row ***************************
           Name: bats40sm_cl
         Engine: InnoDB
        Version: 10
     Row_format: Compact
           Rows: 1464102
 Avg_row_length: 297
    Data_length: 436060160
Max_data_length: 0
   Index_length: 603684864
      Data_free: 0
 Auto_increment: 3019688
    Create_time: 2007-12-20 14:27:24
    Update_time: NULL
     Check_time: NULL
      Collation: utf8_general_ci
       Checksum: NULL
 Create_options: 
        Comment: InnoDB free: 12549120 kB
1 row in set (0.23 sec)
Für nen Admin- bzw. Statistik-Bereich würde das wohl auch gehen, oder?

Re: select count(id) from my_table

Posted: 2008-01-09 20:50
by Joe User
Das würde reichen, bleibt nur das Parsen des Output.

Re: select count(id) from my_table

Posted: 2008-01-09 21:11
by simcen
Die Werte sind ganz normale Columns, also mit fetch_array() dahinter und dann mit $row['Rows']...
Selbst ist der Mann ;-)