Эффективно выберите последнюю строку, сгруппированную по столбцу - PullRequest
0 голосов
/ 16 марта 2019

У меня есть таблица:

QUOTE
| id | value | mar_id | date |

И я пытаюсь выбрать самую последнюю строку для каждого mar_id (идентификатор рынка).Мне удалось добиться того, что мне нужно, с помощью запроса ниже:

SELECT 
q.*
FROM quote q
WHERE q.date = (
  SELECT MAX(q1.date)
  FROM quote q1
  WHERE q.mar_id = q1.mar_id
)

Однако я обнаружил, что запрос невероятно медленный (> 60 с), поскольку моя база данных уничтожает соединение.

Я сделал EXPLAIN, чтобы выяснить, почему и получил результат:

Explain Plan

У меня есть составной уникальный индекс QUO_UQ на mar_id, dateкоторый, кажется, привыкает.

логически это не кажется таким сложным для выполнения запросом, что я могу сделать, чтобы сделать это более эффективно?

Ответы [ 3 ]

1 голос
/ 16 марта 2019

Пример некоррелированного подзапроса

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;
0 голосов
/ 16 марта 2019

Ваш запрос в порядке:

SELECT q.*
FROM quote q
WHERE q.date = (SELECT MAX(q1.date)
                FROM quote q1
                WHERE q.mar_id = q1.mar_id
               );

Я рекомендую индекс на quote(mar_id, date).Вероятно, это самый быстрый способ получить ваш результат.

РЕДАКТИРОВАТЬ:

Мне любопытно, если вы обнаружите, что это использует индекс:

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
               );
0 голосов
/ 16 марта 2019
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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...