views:

43

answers:

3

I have the following query which is takin 3 seconds on a table of 1500 rows, does someone know how to simplify it?

SELECT dealers.name, dealers.companyName, dealer_accounts.balance
FROM dealers 
  INNER JOIN dealer_accounts
  ON dealers.id = dealer_accounts.dealer_id
WHERE dealer_accounts.id = (
  SELECT id
  FROM dealer_accounts
  WHERE dealer_accounts.dealer_id = dealers.id
  AND dealer_accounts.date < '2010-03-30'
  ORDER BY dealer_accounts.date DESC, dealer_accounts.id DESC
  LIMIT 1
)
ORDER BY dealers.name

I need the latest dealer_accounts record for each dealer by a certain date with the join on the dealer_id field on the dealer_accounts table. This really should be simple, I don't know why I am struggling to find something.

A: 

You could try using two queries instead of one, i.e. getting the ID and using that instead of a sub query. This may tell you which query is slow. Also I believe MySQL will cache the separate queries, speeding up multiple requests.

Do you have indexes on the tables? in general you should index any columns that you filter or sort on. In your example that would be the dealer_accounts.date column certainly.

I'm assuming the ID fields are primary keys, if so, it's pointless adding dealer_accounts.id to the sorting criteria.

DisgruntledGoat
I was really wanting to see if I was missing the obvious, it turns out the query isn't too too bad, all I want is the latest account so I was thinking surely there would be an easier way to do it.But your point on indexing was right, I changed the db to innodb and added an index on dealer_id and got it down to 302 ms which although isnt amazingly quick, it is still quite reasonable and 10 times faster than what I had. Thanks again for your help
Richard
A: 

I'm not sure why you can't just do this:

SELECT 
   dealers.name, dealers.companyName, dealer_accounts.balance
FROM 
   dealers, dealer_accounts
WHERE 
  WHERE dealer_accounts.dealer_id = dealers.id
  AND dealer_accounts.date < '2010-03-30'
ORDER BY dealer_accounts.date DESC, dealer_accounts.id DESC

Try MySQL EXPLAIN PLAN on your query. If you see TABLE SCAN, that's why your query is so slow.

I don't know what indexes you have on your tables, but adding appropriate ones might help. EXPLAIN PLAN could tell you where they're lacking.

duffymo
Unfortunately the syntax in your example wasn't correct, but your Explain advise was helpful for future reference. I myself still dont know why GROUP BY dealer_id ORDER BY date DESC, id DESC won't bring up the latest accounts record. But I managed to speed it up to an acceptable level by switching to innodb and indexing dealer_id. Thanks again for your help
Richard
A: 

Your subquery is run a lot of times, and I suspect that you don't have indices on dealer_accounts.date and dealer_accounts.dealer_id. You should certainly look at the need for filtering on a static field in your subquery. It should be possible to filter on the date once, and then do the subquery on a smaller set.

k_b
I think you are right about the subquery and times run. As for filtering I think you are again right but I didn't want to jump into that as it would complicate it a little more. But indeed changing it to innodb and adding an index on dealer_id sped it up 10 times! I am happy with that... Thanks for your help
Richard