31

I'm just wondering which method is the most effective if I'm literally just wanting to get the number of rows in a table.

$res = mysql_query("SELECT count(*) as `number` FROM `table1`");
$count = mysql_fetch_result($res,0,'number');

or

$res = mysql_query("SELECT `ID` FROM `table1`");
$count = mysql_num_rows($res);

Anyone done any decent testing on this?

6 Answers 6

32

mysql_query() transfers all result records from the MySQL into the php pcrocess before it returns (unlike mysql_unbufferd_query()). That alone would make the mysql_num_rows() version slower.

Furthermore for some engines (like MyISAM) MySQL can serve a Count(*) request from the index of the table without hitting the actual data. A SELECT * FROM foo on the other hand results in a full table scan and MySQL has to read every single dataset.

1
  • Thank you everyone for your posts, had to pick one. VolkerK's answer was definitive and informative. Thanks :)
    – Joel
    Commented Mar 21, 2010 at 0:24
11

Test in database with more then 2300000 rows, type:InnoDB, size near 1 GiB, using xhprof

test1:

    ....SELECT COUNT(id) as cnt FROM $table_name....;
       row= mysqli_fetch_assoc($res2);
   echo $row['cnt'];
        //result1:
        1,144,106
        1,230,576
        1,173,449
        1,163,163
        1,218,992

test2:

....SELECT COUNT(*) as cnt FROM $table_name....;
       row= mysqli_fetch_assoc($res2);
   echo $row['cnt'];
//result2:
1,120,253
1,118,243   
1,118,852
1,092,419
1,081,316

test3:

 ....SELECT * FROM $table_name....;
    echo mysqli_num_rows($res2);
    //result3:
7,212,476
6,530,615
7,014,546
7,169,629
7,295,878

test4:

     ....SELECT * FROM $table_name....;
        echo mysqli_num_rows($res2);
        //result4:
1,441,228
1,671,616
1,483,050
1,446,315
1,647,019

conclusion: The fastest method is in the test2 :

....SELECT COUNT(*) as cnt FROM $table_name....;
       row= mysqli_fetch_assoc($res2);
   echo $row['cnt'];
6

Definitely the first. MySQL can usually do this by looking at an index rather than the whole table, and if you use MyISAM (the default), the row count for the table is stored in the table metadata and will be returned instantly.

Your second method will not only read the entire table into memory but also send it to the client through the network before the client counts the rows. Extremely wasteful!

1

I don't really think any testing is needed.

Doing the COUNT in the SQL query

1) Sends only one row of data back the to client (instead of every row)

2) Lets SQL do the count for you which is likely always going to be faster than PHP.

0

I guess count(1) will be even faster:

$res = mysql_query("SELECT count(1) as `number` FROM `table1`");
$count = mysql_fetch_result($res,0,'number');

Although haven't tried the proposed methods, the first makes database fetch all the records and count them in the database, the second makes database fetch a separate field for all the records and count the number of results on the server.
As a rule of thumb the less data you fetch for a particular record the less time it will take therefore I'd vote for updated first method (fetching constant for every record and counting the number of constants fetched).

3
  • 1
    If storage engine is MyISAM and there are no WHERE conditions, count(*) will be faster, because exact record count is stored for MyISAM tables. Commented Mar 21, 2010 at 0:00
  • 1
    Your guess could backfire - COUNT(*) is the idiomatic way of getting the size of a result set, and any database worth its salt will be optimized for it. Commented Mar 21, 2010 at 0:00
  • 2
    And the * in Count(*) means "Don't look at the data, just count the records" as opposed to Count(colname).
    – VolkerK
    Commented Mar 21, 2010 at 0:07
-3

Using Count with index and inodb makes it too much slow, but when use it with mysqli_num_rows it returns without any delay. you can check mysqli_num_rows result at http://ssajalandhar.org/generalinstruction-0-1-0.html it wouldn't take fraction of second to load. For me mysqli works awesome.

Not the answer you're looking for? Browse other questions tagged or ask your own question.