I have these tables and queries as defined in sqlfiddle.
First my problem was to group people showing LEFT JOINed visits rows with the newest year. That I solved using subquery.
Now my problem is that that subquery is not using INDEX defined on visits table. That is causing my query to run nearly indefinitely on tables with approx 15000 rows each.
Here’s the query. The goal is to list every person once with his newest (by year) record in visits table.
Unfortunately on large tables it gets real sloooow because it’s not using INDEX in subquery.
SELECT *
FROM people
LEFT JOIN (
SELECT *
FROM visits
ORDER BY visits.year DESC
) AS visits
ON people.id = visits.id_people
GROUP BY people.id
Does anyone know how to force MySQL to use INDEX already defined on visits table?
Your query:
First, is using non-standard SQL syntax (items appear in the
SELECTlist that are not part of theGROUP BYclause, are not aggregate functions and do not sepend on the grouping items). This can give indeterminate (semi-random) results.Second, ( to avoid the indeterminate results) you have added an
ORDER BYinside a subquery which (non-standard or not) is not documented anywhere in MySQL documentation that it should work as expected. So, it may be working now but it may not work in the not so distant future, when you upgrade to MySQL version X (where the optimizer will be clever enough to understand thatORDER BYinside a derived table is redundant and can be eliminated).Try using this query:
The: SQL-fiddle
A compound index on
(id_people, year)would help efficiency.A different approach. It works fine if you limit the persons to a sensible limit (say 30) first and then join to the
visitstable: