views:

354

answers:

2

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

+2  A: 

This is one form of the perennial question "why does MySQL stop using indexes when my table gets big?" Basically, there's a point past which using indexes stops being helpful and starts hurting your query, and MySQL's query optimizer is designed to take that into account. If you don't believe it, you can use FORCE INDEX to make it use a particular index, run your query with and without the index and see what results you get.

The different in behavior with (1,2) and (1,10) is probably because category 2 is much more heavily used than category 10.

chaos
This is correct I think the term is called key cardinality. For instance, if 90% of your rows are category_id = 1 and 10% of your rows are category_id = 2 then it won't bother using the category_id key anymore. (the actual numbers are made up I don't believe there is a hard and fast rule for when mysql stops using your key).
Hardwareguy
A: 

Thanks, but the bad news is that my category_id table isn't big! Does this change anything?

youyou
Don't respond in answers. Edit you question to include this extra information.
jmucchiello
It's not the category table that's big, or whose bigness is relevant, it's product.
chaos
I mean the product table isn't big. Sorry.
youyou