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 -- Posted via http://www.ruby-forum.com/.
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. http://www.postgresql.org/docs/8.3/static/using-explain.html HTH, Perry -- Posted via http://www.ruby-forum.com/.
Youyou Semsem 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. -- Posted via http://www.ruby-forum.com/.
On Jun 10, 2:52 am, Robert Walker <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> 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