Foreign Key (Mysql/Rails)

Hi,

I am using a Mysql table products which has a foreign key category_id on
the categories table

the foreign key constraint is defined (Innodb engine).

I noticed that when I run EXPLAIN SELECT * from products where
category_id=1;

it uses the foreign key, so I see type=Range and Key: my_foreign_key

But when I run EXPLAIN SELECT * from products where category_id IN
(1,10);

it uses a full table scan: type=ALL, Key:NULL!!!

Ironically, when I do EXPLAIN SELECT * from products where category_id
IN (1,2); It uses type-range and Key: My_foreign_key!

So I guess there is a problem when the category_id uses values that are
not contiguous.

Any ideas why?

Thanks

I happen to be reading about this last night except I was reading about
it in the PostgreSQL manual.

In the case of PostgreSQL, the planner searches for the least expensive
plan and uses different plans based upon the “selectivity” of the
constraint.

The PostgreSQL doc may give you a clue what MySQL is doing… maybe not.

HTH,
Perry

Youyou S. wrote:

Hi,

I am using a Mysql table products which has a foreign key category_id on
the categories table

the foreign key constraint is defined (Innodb engine).

The constraint matters not, for performance. What is important is that
the foreign key is indexed.

I noticed that when I run EXPLAIN SELECT * from products where
category_id=1;

it uses the foreign key, so I see type=Range and Key: my_foreign_key

But when I run EXPLAIN SELECT * from products where category_id IN
(1,10);

it uses a full table scan: type=ALL, Key:NULL!!!

Of course, there is no index in the foreign key so MySQL has no way to
optimize.

Ironically, when I do EXPLAIN SELECT * from products where category_id
IN (1,2); It uses type-range and Key: My_foreign_key!

So I guess there is a problem when the category_id uses values that are
not contiguous.

Not ironic to me. I assume MySQL optimization recognizes the contiguous
nature of the values and applies the appropriate optimization.

On Jun 10, 2:52 am, Robert W. [email protected]
wrote:

Of course, there is no index in the foreign key so MySQL has no way to
optimize.

When you add a foreign key mysql implicitly adds an index.

Ironically, when I do EXPLAIN SELECT * from products where category_id
IN (1,2); It uses type-range and Key: My_foreign_key!

So I guess there is a problem when the category_id uses values that are
not contiguous.

Not ironic to me. I assume MySQL optimization recognizes the contiguous
nature of the values and applies the appropriate optimization.

It can be more complicated than that. Assume for example that
categories is a small table. Mysql might decide that the cost of the
random seeks to get the index for id=1 and then the corresponding row
from the categories table, then going back to the index and seeking
for id=2 and then going back to the categories table is actually
smaller than just reading the whole of the categories table in one go.
There are a lot of factors in this sort of thing although mysql can
get it wrong. If you thing you know better, there’s always USE INDEX
(…) or FORCE INDEX(…) to tell mysql that it really should try and
use the index you are telling it to.

Fred