Strange case where the index dont work properly

I have a very strange case, where a index for a foreign key dont seem to work.

The two columns in the invoice table “matrix_log_id” and “commission_log_id” actually link to the matrix_log table and the “matrix_log_id” column there, they just refer to two different case types (invoice, commission payout).

The foreign key restrictions work as they should, but it seems the index of the column does not work properly. When I do a EXPLAIN on the query below, it says that it use the “fk_invoice_matrix_log2” index, and that it search through 40299 rows (The index on matrix_log_id works as it should).

If I now add an index on the column (ALTER TABLE invoice ADD INDEX test (commission_log_id):wink: the result is that it use the new index (test) and it match at once. (Edit: I was assuming that it used the new index, when looking I see that it still chose the foreign key index which makes sense as its cardinality is higher, but it does not explain why it goes from looking through 40k rows to match at once after the new index is added).

What I am wondering on here, is if I have misunderstood something regarding indexes that also have a foreign key constraint. As I have always believed that you should never have two indexes on the same column (i.e. for one column, not considering if you index multiple columns into one index).

If anyone can share some insight on what is happening here it would be great.

Thanks

Note. The table code, query and explains are below.

The table in question:


CREATE  TABLE IF NOT EXISTS `invoice` (
  `invoice_id` INT NOT NULL AUTO_INCREMENT ,
  `matrix_log_id` INT NULL ,
  `commission_log_id` INT NULL ,
  PRIMARY KEY (`invoice_id`) ,
  INDEX `fk_invoice_matrix_log1` (`matrix_log_id` ASC) ,
  INDEX `fk_invoice_matrix_log2` (`commission_log_id` ASC) ,
  CONSTRAINT `fk_invoice_matrix_log1`
    FOREIGN KEY (`matrix_log_id` )
    REFERENCES `matrix_log` (`matrix_log_id` )
    ON DELETE RESTRICT
    ON UPDATE CASCADE,
  CONSTRAINT `fk_invoice_matrix_log2`
    FOREIGN KEY (`commission_log_id` )
    REFERENCES `matrix_log` (`matrix_log_id` )
    ON DELETE RESTRICT
    ON UPDATE CASCADE)
ENGINE = InnoDB

The query in question:


SELECT
	[removed as it has no relevance]
FROM
	matrix_log as log
	LEFT JOIN matrix_log_detailed as detailed
		USING (matrix_log_id)
	LEFT JOIN matrix_log_funding as fund
		ON (log.matrix_log_id=fund.matrix_log_id)
	LEFT JOIN tosb_info as tosb
		ON (log.matrix_log_id=tosb.matrix_log_id)
	LEFT JOIN invoice
		ON (log.matrix_log_id=invoice.matrix_log_id)
	LEFT JOIN invoice as comm
		ON (log.matrix_log_id=comm.commission_log_id)
	INNER JOIN matrix_import as imp
		ON (log.matrix_user_id=imp.matrix_user_id)
WHERE
	log.matrix_user_id=:user_id
ORDER BY
	log.matrix_log_date DESC

This is the first explain:


id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	log	ref	fk_matrix_log_matrix_user1	fk_matrix_log_matrix_user1	4	const	5	Using where; Using filesort
1	SIMPLE	imp	ref	fk_matrix_import_matrix_user1	fk_matrix_import_matrix_user1	5	const	1	Using where
1	SIMPLE	detailed	ref	fk_matrix_log_detailed_matrix_log1	fk_matrix_log_detailed_matrix_log1	4	lgn.log.matrix_log_id	1	
1	SIMPLE	fund	ref	fk_matrix_funding_matrix_log1	fk_matrix_funding_matrix_log1	4	lgn.log.matrix_log_id	1	
1	SIMPLE	tosb	ref	matrix	matrix	5	lgn.log.matrix_log_id	1	
1	SIMPLE	invoice	ref	fk_invoice_matrix_log1	fk_invoice_matrix_log1	5	lgn.log.matrix_log_id	1	Using index
1	SIMPLE	comm	ref	fk_invoice_matrix_log2	fk_invoice_matrix_log2	5	lgn.log.matrix_log_id	40299	Using index

This is the second explain:


id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	log	ref	fk_matrix_log_matrix_user1	fk_matrix_log_matrix_user1	4	const	5	Using where; Using filesort
1	SIMPLE	imp	ref	fk_matrix_import_matrix_user1	fk_matrix_import_matrix_user1	5	const	1	Using where
1	SIMPLE	detailed	ref	fk_matrix_log_detailed_matrix_log1	fk_matrix_log_detailed_matrix_log1	4	lgn.log.matrix_log_id	1	
1	SIMPLE	fund	ref	fk_matrix_funding_matrix_log1	fk_matrix_funding_matrix_log1	4	lgn.log.matrix_log_id	1	
1	SIMPLE	tosb	ref	matrix	matrix	5	lgn.log.matrix_log_id	1	
1	SIMPLE	invoice	ref	fk_invoice_matrix_log1	fk_invoice_matrix_log1	5	lgn.log.matrix_log_id	1	Using index
1	SIMPLE	comm	ref	fk_invoice_matrix_log2,test	fk_invoice_matrix_log2	5	lgn.log.matrix_log_id	1	Using index