sql - 左外连接与嵌套聚合选择查找表中最新行的好处是什么?

标签 sql oracle

我在做:

select * from mytable y
where y.year = (select max(yi.year) 
                from mytable yi
                where yi.person = y.person)

从性能方面来看,它比以下情况更好还是更差:

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

解释计划/轶事证据尚无定论,所以我想知道总的来说一个是否比另一个更好。

最佳答案

“一般来说”,两种查询都可以根据数据分布产生不同的执行计划。

但是,假设您的第二个查询实际上是这样的:

SELECT  y.*
FROM    mytable y
LEFT JOIN
        mytable y2
ON      y2.person = y.person
        AND y2.year > y.year
WHERE   y2.year IS NULL

LEFT JOIN 版本很可能会更快,因为它将优化为 HASH ANTI JOINHASH 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) 上的重复项到。

关于sql - 左外连接与嵌套聚合选择查找表中最新行的好处是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5871434/

相关文章:

sql - 关键字 'with' 附近的语法不正确。

SQL - WHERE 中的 CASE 表达式

sql - 计算连接表的列

oracle - 将 Varchar2 形式的返回值 default(4000) 更改为 (10char)?

使用 Azure Devops Pipeline 部署 Oracle 对象

sql - 来自 ODBC 的 SQL 查询的 Excel 参数 "Error - No Value given for one or more required parameters when using question mark ` WHERE XXX = ?`

mysql - 使 MAX IF AS 与多个输入一起工作

sql - Oracle PL/SQL 字符串比较问题

sql - 如何从 select 执行 Oracle SQL 更新?

sql - Oracle JOIN 3 表 - 哪种方式有效或有什么区别