目录

Oracle 11g数据库与某个表的最新一笔记录进行关联

背景:最近在写Power BI的看板,而表中的数据都是上亿条记录的,各个表的关联关系非常复杂。而对于某些表,用户又只要看到最新的数据。

举个例子,比如A关联B表,正常来说看板是这样写的。

复制代码
select * from a
left join b
on a.xx = b.xx

但是实际上,用户只需要B表中,按某些字段划分的最新记录。

我就写成了这样:

复制代码
WITH C AS
 (SELECT B.*,
         ROW_NUMBER() OVER(PARTITION BY B.XXX,B.XXXXX ORDER BY B.INDATE DESC) AS rn
    FROM B )
SELECT *
FROM A
LEFT JOIN C
ON A.XX = C.XX AND C.RN = 1;

这个sql语句中用到了row_number()的窗口函数(Oracle内置函数),它根据B表中的XXX和XXXXX字段分组,然后根据B表中的INDATE进行了排序。

with c as 则是将结果集存放到内存中,建一个临时表c存储这些结果数据,然后a表直接跟c关联,c.rn = 1 就是最新的记录。

但是,由于我所在公司的数据量太大,这样跑的效率仍然很低。

于是,我改成了如下写法:

复制代码
WITH c AS (
    SELECT 
        b.xx,
        b.xxxxx,
        MAX(b.indate) AS indate
    FROM 
        scstadmin.b
    GROUP BY 
        b.xx,
        b.xxxxx
)
select * from a
left join b
on a.xx = b.xx 
and b.indate = (select indate from c where c.xx=b.xx and c.xxxxx= b.xxxxx);

这样写的好处是:

1.通过 WITH 子句 (c) 预先计算出每个 xx 最新的 indate,避免对整个表使用 ROW_NUMBER()。减少数据库对无用信息的计算次数,效率自然提升。

2.在主查询中将 b.indate 与子查询的最大时间进行匹配,从而仅选择最新的记录。

当然,语法优化只能优化一部分效率,最简单且有效的写法是对b表中的XX、XXXXX和indate字段做复合索引:(XX, XXXXX,INDATE DESC)。这可以极大地提高 ROW_NUMBER() 的性能。

一小段小记,希望可以帮到大家。

本文是转载文章,点击查看原文
如有侵权,请联系 xyy@jishuzhan.net 删除
相关推荐
落落落sss12 分钟前
nexus的使用
服务器·数据库·mongodb·云原生·eureka
熊文豪25 分钟前
崖山数据库(YashanDB)部署全流程详解
数据库·崖山数据库·yashan·崖山数据库部署全流程·yasboot·yassql·yca认证
野生派蒙25 分钟前
MySQL 安装配置(完整教程)
数据库·mysql
度假的小鱼30 分钟前
Win11系统下Oracle11g数据库下载与安装使用教程
数据库·oracle11g安装·oracle11g下载
溟洵30 分钟前
【MySQL】事务是个啥?(一文带你了解 为什么要有事务、事务在mysql中的出现情况以及事务的四大特性)
linux·运维·数据库·后端·mysql
小明同学的开发日常31 分钟前
【Spring AI】05. 向量数据库-Redis
数据库·人工智能·spring
m0_5485147732 分钟前
五款MySQL 可视化客户端软件,你选择哪一种?
数据库·mysql
ljh5746491191 小时前
mysql select distinct 和 group by 哪个效率高
数据库·mysql
jsxztshaohaibo1 小时前
Token登录授权、续期和主动终止的方案(Redis+Token(非jwtToken))
java·数据库·redis·缓存
啥都不会的小泽1 小时前
MariaDB 10.6.21(安装后实际版本为10.6.19)
数据库·mariadb