«В общем», оба запроса могут создавать разные планы выполнения в зависимости от распределения данных.
Однако, если предположить, что ваш второй запрос действительно такой:
SELECT y.*
FROM mytable y
LEFT JOIN
mytable y2
ON y2.person = y.person
AND y2.year > y.year
WHERE y2.year IS NULL
, *Версия 1006 *, скорее всего, будет быстрее, так как она будет оптимизирована либо до HASH ANTI JOIN
, либо HASH JOIN
с фильтром, в зависимости от того, есть у вас индекс на mytable (person, year)
или нет, а также от некоторых других условий.Версия подзапроса не может быть оптимизирована для анти-объединения.
Скорее всего, эти запросы окажутся более эффективными:
SELECT *
FROM mytable y
WHERE (y.person , y.year) IN
(
SELECT person, MAX(year)
FROM mytable
GROUP BY
person
)
или
SELECT *
FROM (
SELECT y.*,
DENSE_RANK() OVER (PARTITION BY person ORDER BY year DESC) dr
FROM mytable y
)
WHERE dr = 1
с первымодин из них более эффективен в случае нескольких человек и нескольких лет на человека, а второй более эффективен в противоположном случае.
Вы можете заменить DENSE_RANK
на ROW_NUMBER
, что позволит вам получитьизбавьтесь от дубликатов на person, MAX(year)
, если захотите.