In this query:
select count(*) from largetable;
a secondary index is chosen:
mysql> explain select count(*) from largetable;
+----+-------------+------------+-------+---------------+------+---------+------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+-------+---------------+------+---------+------+----------+-------------+
| 1 | SIMPLE | largetable | index | NULL | iif | 5 | NULL | 50000169 | Using index |
+----+-------------+------------+-------+---------------+------+---------+------+----------+-------------+
1 row in set (0.00 sec)
mysql> select count(*) from largetable;
+----------+
| count(*) |
+----------+
| 50000000 |
+----------+
1 row in set (5 min 52.02 sec)
Whereas forcing usage of the clustered index:
select count(*) from largetable force index (primary);
gives better performance:
mysql> explain select count(*) from largetable force index (primary);
+----+-------------+------------+-------+---------------+---------+---------+------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+-------+---------------+---------+---------+------+----------+-------------+
| 1 | SIMPLE | largetable | index | NULL | PRIMARY | 4 | NULL | 50000169 | Using index |
+----+-------------+------------+-------+---------------+---------+---------+------+----------+-------------+
1 row in set (0.00 sec)
mysql> select count(*) from largetable force index (primary);
+----------+
| count(*) |
+----------+
| 50000000 |
+----------+
1 row in set (2 min 23.07 sec)
So that's 5 minutes and 52 seconds versus 2 minutes and 23 seconds.
I am looking to understand why MySQL's query optimizer chooses a secondary index.
There are 50 million rows in the table, with ids from 1 to 50 million (no gaps), that were inserted sequentially.
This is on MySQL 5.5.11.
Here's the table's design:
create table largetable (
id int primary key auto_increment,
field1 int,
index iif (field1),
... some more columns, some with indexes ... each row is about 115 bytes ...
);