Where the open source database community meets: Use code PERCONA75 and secure your spot for Percona Live.  Register

MySQL Optimizer and Innodb Primary Key

October 3, 2006
Author
Peter Zaitsev
Share this Post:

Innodb primary key is special in many senses and I was always wondering how well MySQL is integrated with Innodb to take advantage of these special features.

Lets see which things work and which things do not:

I used the following simple table for tests:

“myisam” is same table created with MyISAM storage engine used to show difference:

MySQL Optimizer correctly knows Innodb tables is clustered by primary key in the sense it would not be faster to do external filesort than to do lookups in primary key order:

MySQL Optimizer is also able to figure out every key also holds primary key value so primary key value can be read from index, making some queries index covered which previously was not: Notice “Using Index” difference

MySQL However is unable to benefit from the fact each index internally has primary key as last column, so key on (a) is effectively key on (a,id) which means MySQL could skip filesort if ordering is done by primary key:

Filesort should be avoided in this case which it is not. I now filed it as a
bug while I do not really think it would be fixed soon

0 0 votes
Article Rating
Subscribe
Notify of
guest

9 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Roland Volkmann
Roland Volkmann
19 years ago

Hello Peter,

as long as the bug is not fixed, you can define key a as “KEY a (a,id)” to avoid filesort. I did so in my projects.

With best regards

Roland

grantsucceeded
grantsucceeded
19 years ago

Peter:
It is not true that primary key lookup is faster than filesort, or at least should not be true.

If one is sorting a significant number of rows, sort is faster because it can do sequential IOs then O(logN) sort instead of random IOs.

Raj
Raj
18 years ago

Will Primary key improve performance ?

Geo
Geo
18 years ago

This is now fixed, at least my tests show so

CREATE TABLE pricesbig_inno (
id int(10) unsigned NOT NULL,
url_id int(10) unsigned NOT NULL,
product_id int(10) unsigned NOT NULL,
PRIMARY KEY (product_id,id),
KEY id (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

mysql> EXPLAIN SELECT id, product_id FROM pricesbig_inno WHERE id =1515;
+—-+————-+—————-+——+—————+——+———+——-+——+————-+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+—-+————-+—————-+——+—————+——+———+——-+——+————-+
| 1 | SIMPLE | pricesbig_inno | ref | id | id | 4 | const | 1 | Using index |
+—-+————-+—————-+——+—————+——+———+——-+——+————-+
1 row in set (0.00 sec)

Cyril Scetbon
Cyril Scetbon
17 years ago

It seems to be not the case anymore in 5.1 :

mysql> EXPLAIN SELECT id FROM innodb WHERE a=3 ORDER BY id G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: innodb
type: ref
possible_keys: a
key: a
key_len: 5
ref: const
rows: 3
Extra: Using where; Using index
1 row in set (0.51 sec)

Far
Enough.

Said no pioneer ever.
MySQL, PostgreSQL, InnoDB, MariaDB, MongoDB and Kubernetes are trademarks for their respective owners.
© 2026 Percona All Rights Reserved