views:

11

answers:

0

One of the more annoying things about InnoDB is that although it supports foreign keys it requires that foreign key columns in the referencing table be indexed. While that's often a good idea it certainly isn't always one.

Take for example an orders table with ~20 columns. Aside from the single column primary key and perhaps the created and updated timestamp columns, the rest are simply foreign keys. For efficiency lets assume these are all appropriately sized unsigned integer variations (tinyint, smallint, etc).

So alright we take the performance hit on insert on doing integrity checks for each foreign key column against the associated relatively small lookup table using a foreign key to primary key join. That'll be very fast. The problem though is that with each foreign key column in the orders table being indexed, the engine will have to update these indexes as well. That can be a serious problem.

MySQL will fortunately cleverly batch these updates and commit the insert "early". Still the engine inevitably end up wasting space and time to do the updates to the indexes regardless. So why are indexes required for these columns? Is there an alternative transactional ACID compliant storage engine that does not require indexes of all foreign keys?

Here's an example of a table with a foreign key column that's silly to have indexed:

create table currencies (
    currency_id tinyint unsigned not null primary key,
    currency_code enum('USD', 'GBP', 'EUR') not null
);

create table orders (
    order_id int unsigned not null primary key auto_increment,
    currency_id tinyint unsigned not null,
    foreign key (currency_id) references currencies (currency_id)
);

So with 30 million orders roughly evenly distributed amongst the currencies. What possible use would there be for a currency_id index above? Answer: none really. You'd be better off doing a table scan than an index lookup even if you wanted just find the USD rows as the combined work of finding the index pages and associated data pages) would be more expensive than a single full table scan.