SELECT i.*, i.id IN ( SELECT id FROM w WHERE w.status='active') AS wish FROM i INNER JOIN r ON i.id=r.id WHERE r.member_id=1 && r.status='active' ORDER BY wish DESC LIMIT 0,50
That’s a query that I’m trying to run. It doesn’t scale well, and I’m wondering if someone here can tell me where I could improve things. I don’t join w to r and i because I need to show rows from i that are unrepresented in w. I tried a left join, but it didn’t perform too well. This is better, but not ideal yet. All three tables are very large. All three are indexed on the fields I’m joining and selecting on.
Any comments, pointers, or constructive criticisms would be greatly appreciated.
EDIT Addition:
I should have put this in my original question. It’s the EXPLAIN as return from SQLYog.
id|select_type |table|type |possible_keys|key |key_len|ref |rows|Extra| 1 |PRIMARY |r |ref |member_id,id |member_id|3 |const|3120|Using where; Using temporary; Using filesort 1 |PRIMARY |i |eq_ref |id |id |8 |r.id |1 | 2 |DEPENDENT SUBQUERY|w |index_subquery|id,status |id |8 |func |8 |Using where
EDIT le dorfier – more comments …
I should mention that the key for w is (member_id, id). So each id can exist multiple times in w, and I only want to know if it exists.
WHERE x IN ()is identical to anINNER JOINto aSELECT DISTINCTsubquery, and in general, a join to a subquery will typically perform better if the optimizer doesn’t turn theINinto aJOIN– which it should:Which, would probably be equivalent to this if you don’t need the
DISTINCT:Please post your schema.
If you are using wish as an existence flag, try:
You can use the same technique with a
LEFT JOINto aSELECT DISTINCTsubquery. I assume you aren’t specifying thew.member_idbecause you want to know if any members have this? In this case, definitely use theSELECT DISTINCT. You should have an index withidas the first column onwas well in order for that to perform: