Reputation: 7141
I have a table:
QUOTE
| id | value | mar_id | date |
And I am trying to select the latest row for each mar_id
(market id). I have managed to achieve what I need from the query below:
SELECT
q.*
FROM quote q
WHERE q.date = (
SELECT MAX(q1.date)
FROM quote q1
WHERE q.mar_id = q1.mar_id
)
However I find that the query is incredibly slow (>60s), to the extent my database kills the connection.
I did an EXPLAIN
to find out why and got the result:
I have a composite unique index QUO_UQ
on mar_id, date
which appears to be getting used.
logically this doesn't seem such a tough query to run, what can I do to do this more efficiently?
Upvotes: 1
Views: 60
Reputation: 1269493
Your query is fine:
SELECT q.*
FROM quote q
WHERE q.date = (SELECT MAX(q1.date)
FROM quote q1
WHERE q.mar_id = q1.mar_id
);
I recommend an index on quote(mar_id, date)
. This is probably the fastest method to get your result.
EDIT:
I'm curious if you find that this uses the index:
SELECT q.*
FROM quote q
WHERE q.date = (SELECT q1.date
FROM quote q1
WHERE q.mar_id = q1.mar_id
ORDER BY q1.date DESC
LIMIT 1
);
Upvotes: 0
Reputation: 63
select * from (
select mar_id, [date],row_number() over (partition by mar_id order by [date] desc ) as [Rank] from
qoute
group by mar_id, [date]) q where Rank = 1
Upvotes: 0
Reputation: 33935
An example of an uncorrelated subquery
SELECT x.*
FROM quote x
JOIN
( SELECT mar_id
, MAX(date) date
FROM quote
GROUP
BY mar_id
) y
ON y.mar_id = x.mar_id
AND y.date = x.date;
Upvotes: 1