我正在做:
select * from mytable y
where y.year = (select max(yi.year)
from mytable yi
where yi.person = y.person)
Run Code Online (Sandbox Code Playgroud)
从性能方面来看,这是好还是坏:
select y.* from mytable y
left outer join mytable y2
on y.year < y2.year
and y.person = y2.person
where y2.year is null
Run Code Online (Sandbox Code Playgroud)
解释计划/轶事证据是不确定的,所以我想知道一般情况下一个是否优于另一个.
"通常",两个查询都可以根据数据分布生成不同的执行计划.
但是,假设您的第二个查询实际上是这样的:
SELECT y.*
FROM mytable y
LEFT JOIN
mytable y2
ON y2.person = y.person
AND y2.year > y.year
WHERE y2.year IS NULL
Run Code Online (Sandbox Code Playgroud)
,LEFT JOIN版本很可能会更快,因为它将被优化为a HASH ANTI JOIN或a HASH JOINwith filter,具体取决于你是否有索引mytable (person, year)和其他条件.子查询版本无法针对反连接进行优化.
您可能最有可能发现这些查询更有效:
SELECT *
FROM mytable y
WHERE (y.person , y.year) IN
(
SELECT person, MAX(year)
FROM mytable
GROUP BY
person
)
Run Code Online (Sandbox Code Playgroud)
要么
SELECT *
FROM (
SELECT y.*,
DENSE_RANK() OVER (PARTITION BY person ORDER BY year DESC) dr
FROM mytable y
)
WHERE dr = 1
Run Code Online (Sandbox Code Playgroud)
,第一个在人数很多,每人几年的情况下更有效率,第二个在相反的情况下效率更高.
如果你想要的话,你可以DENSE_RANK用ROW_NUMBER它替换你可以摆脱重复person, MAX(year).