If I have a table such as
CREATE TABLE foo
(
A TINYINT PRIMARY KEY AUTO_INCREMENT,
B TINYINT NOT NULL,
C TINYINT NOT NULL,
D TINYINT NOT NULL,
INDEX (B),
INDEX (C),
INDEX (D),
INDEX (B, C, D)
);
);
If I then write a query such as
SELECT * FROM foo
WHERE B = 1
ORDER BY A DESC;
With certain data sets, MySQL seems to default to using filesort instead of just using the single column index on column B.
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | SIMPLE | foo | ref | B,B_2 | B_2 | 1 | const | 2 | 100 | Using where; Using index; Using filesort |
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| foo | 0 | PRIMARY | 1 | A | A | 4 | NULL | NULL | BTREE | |||
| foo | 1 | B | 1 | B | A | 4 | NULL | NULL | BTREE | |||
| foo | 1 | C | 1 | C | A | 4 | NULL | NULL | BTREE | |||
| foo | 1 | D | 1 | D | A | 4 | NULL | NULL | BTREE | |||
| foo | 1 | B_2 | 1 | B | A | 4 | NULL | NULL | BTREE | |||
| foo | 1 | B_2 | 2 | C | A | 4 | NULL | NULL | BTREE | |||
| foo | 1 | B_2 | 3 | D | A | 4 | NULL | NULL | BTREE |
Note that if INDEX HINTS are used, then it does use the single column and no longer uses filesort, which seems to be better. I'd like MySQL to figure that out though.
explain extended
SELECT * FROM foo USE INDEX (B)
WHERE B = 1
ORDER BY A DESC;
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | SIMPLE | foo | ref | B | B | 1 | const | 2 | 100 | Using where |