I have a database created with a GUI tool and I’ve noticed what appears to be an inconsistent use of KEY (aka INDEX) definitions:
CREATE TABLE `foo_bar` (
`foo_id` int(10) unsigned NOT NULL,
`bar_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`foo_id`, `bar_id`),
KEY `foo_bar_fk2` (`bar_id`), -- <== ???
CONSTRAINT `foo_bar_fk1` FOREIGN KEY (`foo_id`) REFERENCES `foo` (`foo_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `foo_bar_fk2` FOREIGN KEY (`bar_id`) REFERENCES `bar` (`bar_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci COMMENT='Links between Foo and Bar';
I have the following questions about indexes:
- Is it necessary to explicitly define indexes for primary and foreign keys?
- If it’s not, do you actually get two indexes (and less performance)?
- Is it different in InnoDB and MyISAM (foreign keys apart)?
I’ve been doing some experiments on what you told me and I’d thought I’d share it as answer.
First I create some test tables:
So far, no indexes exists:
Adding a primary key generates an index:
If I add a foreign key on
foo_idit reuses the primary key index since that column is the first one in the index:If I add a foreign key on
bar_id, it creates an index because no existing index can be reused:One of our foreign keys is using the primary key index. That means that we cannot remove such index!
Unless we create an index for the foreign key or we drop the key itself:
The conclusion is that MySQL creates indexes automatically when they’re required for a functionality (but only if they are strictly necessary).