I have the following table:
mysql> select count(*) from employees;
+----------+
| count(*) |
+----------+
| 10000 |
+----------+
1 row in set (0.03 sec)
I do an EXPLAIN
:
mysql> explain select last_name from employees order by last_name;
+----+-------------+-----------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+---------------+------+---------+------+------+----------------+
| 1 | SIMPLE | employees | ALL | NULL | NULL | NULL | NULL | 9894 | Using filesort |
+----+-------------+-----------+------+---------------+------+---------+------+------+----------------+
1 row in set (0.00 sec)
The rows are 9894. I was expecting 10000.
I do:
mysql> analyze table employees;
+-------------------------------------+---------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+-------------------------------------+---------+----------+----------+
| sql_dummy.employees | analyze | status | OK |
+-------------------------------------+---------+----------+----------+
1 row in set (0.04 sec)
and re-run EXPLAIN
:
mysql> explain select last_name from employees order by last_name;
+----+-------------+-----------+------+---------------+------+---------+------+-------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+---------------+------+---------+------+-------+----------------+
| 1 | SIMPLE | employees | ALL | NULL | NULL | NULL | NULL | 10031 | Using filesort |
+----+-------------+-----------+------+---------------+------+---------+------+-------+----------------+
1 row in set (0.01 sec)
The rows are now 10031.
Does anyone know why the rows is never 10000? I have noticed this in other cases as well.
Best Answer
You may find this surprising but that's the behavior of InnoDB.
The InnoDB storage engine does cardinality approximation by walking a few levels down the nonleaf BTREE nodes and takes an educated guess.
I wrote about this a long time ago based on mysqlperformanceblog.com
Jun 21, 2011
: From where does the MySQL Query Optimizer read index statistics?Aug 03, 2011
: When should I rebuild indexes?Feb 23, 2013
: How does mysql deal with queries that touches myisam and innodb tables?Perhaps you could try disabling that behavior by running this:
Setting innodb_stats_on_metadata should stabilize the approximate cardinality and you should get the same cardinality over and over again.