select count(id) from my_table

MySQL, PostgreSQL, SQLite
simcen
Posts: 333
Joined: 2003-02-12 14:35
Location: Bern, Schweiz

select count(id) from my_table

Post by simcen » 2008-01-06 16:38

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

User avatar
Joe User
Project Manager
Project Manager
Posts: 11139
Joined: 2003-02-27 01:00
Location: Hamburg

Re: select count(id) from my_table

Post by Joe User » 2008-01-06 17:36

Lies mal die Antwort von isotopp in http://www.rootforum.org/forum/view ... 23&t=47951
PayPal.Me/JoeUserFreeBSD Remote Installation
Wings for LifeWings for Life World Run

„If there’s more than one possible outcome of a job or task, and one
of those outcomes will result in disaster or an undesirable consequence,
then somebody will do it that way.“ -- Edward Aloysius Murphy Jr.

simcen
Posts: 333
Joined: 2003-02-12 14:35
Location: Bern, Schweiz

Re: select count(id) from my_table

Post by simcen » 2008-01-06 18:52

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)

User avatar
isotopp
Posts: 471
Joined: 2003-08-21 10:21
Location: Berlin

Re: select count(id) from my_table

Post by isotopp » 2008-01-09 11:44

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.

simcen
Posts: 333
Joined: 2003-02-12 14:35
Location: Bern, Schweiz

Re: select count(id) from my_table

Post by simcen » 2008-01-09 19:40

Wie löst man diese Situation, wenn man den Wert statistisch braucht und nicht transaktions-intern? Mutet man dem Client diese x Sekunden zu?

User avatar
Joe User
Project Manager
Project Manager
Posts: 11139
Joined: 2003-02-27 01:00
Location: Hamburg

Re: select count(id) from my_table

Post by Joe User » 2008-01-09 19:50

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.
PayPal.Me/JoeUserFreeBSD Remote Installation
Wings for LifeWings for Life World Run

„If there’s more than one possible outcome of a job or task, and one
of those outcomes will result in disaster or an undesirable consequence,
then somebody will do it that way.“ -- Edward Aloysius Murphy Jr.

simcen
Posts: 333
Joined: 2003-02-12 14:35
Location: Bern, Schweiz

Re: select count(id) from my_table

Post by simcen » 2008-01-09 20:48

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?

User avatar
Joe User
Project Manager
Project Manager
Posts: 11139
Joined: 2003-02-27 01:00
Location: Hamburg

Re: select count(id) from my_table

Post by Joe User » 2008-01-09 20:50

Das würde reichen, bleibt nur das Parsen des Output.
PayPal.Me/JoeUserFreeBSD Remote Installation
Wings for LifeWings for Life World Run

„If there’s more than one possible outcome of a job or task, and one
of those outcomes will result in disaster or an undesirable consequence,
then somebody will do it that way.“ -- Edward Aloysius Murphy Jr.

simcen
Posts: 333
Joined: 2003-02-12 14:35
Location: Bern, Schweiz

Re: select count(id) from my_table

Post by simcen » 2008-01-09 21:11

Die Werte sind ganz normale Columns, also mit fetch_array() dahinter und dann mit $row['Rows']...
Selbst ist der Mann ;-)