GaussDB(DWS)迁移 - oracle兼容 --row_number输出结果不一致

举报
譡里个檔 发表于 2023/05/27 14:53:46 2023/05/27
【摘要】 【问题表现】迁移前后结果集row_number字段值前后不一致,前在DWS上运行不一致【问题分析】这种问题大部分都是因为PARTITION BY 列 + ORDER BY 列组合起来不唯一,导致row_number()开窗函数结果集不稳定。【解决方案】如果不关注PARTITION BY 列 + ORDER BY 列组合值一样的记录的排序,那么可以使用函数rank()代替函数row_numbe...

【问题表现】

迁移前后结果集row_number字段值前后不一致,前在DWS上运行不一致


【问题分析】

这种问题大部分都是因为PARTITION BY 列 + ORDER BY 列组合起来不唯一,导致row_number()开窗函数结果集不稳定。

在Oralce、Postgres等单机版数据上此类查询语句的结果集会呈现稳定的假象。出现这类假象的原因是在单机版火山模型下,在绝大部分场景下,底层输出的顺序会决定最外层输出的顺序。

但是在DWS这类集群架构下,执行过程中可能频繁触发不同DN间的数据流程,以及多实例间并行执行,这种方式会导致中间计算步骤中数据的顺序以及最终输出的顺序(假如查询语句没有显式的ORDER BY,并且ORDER BY可以保证全部记录顺序的话)会被打乱,即和底层扫描上来的顺序不一致,并且是发生极大的变化,这是就会呈现DWS结果集不稳定的“现象”。其本质还是因为PARTITION BY 列 + ORDER BY 列组合起来不唯一,导致row_number()开窗函数结果集不稳定。


【解决方案】

如果不关注PARTITION BY 列 + ORDER BY 列组合值一样的记录的排序,那么可以使用函数rank()代替函数row_number(),二者的区别请戳这里;如果关注PARTITION BY 列 + ORDER BY 列组合值一样的记录的排序,那么需要增 ORDER BY 列,以保证同一个组内所有记录的唯一性。


【案例展示】

某客户反馈进行Orale迁移前,如下SQL结果集稳定;迁移后DWS运行结果和oracle不一致,且DWS本身运行结果不稳定

SELECT 
    no_tax_ind_amt,
    row_number() OVER(PARTITION BY s.actual_arrv_period_id, s.transp_demand_no ORDER BY s.transp_demand_no DESC) pck_rn
FROM fin_dwl_cbchnl.dwl_cbg_cst_tms_freigh_expen_f s
LEFT JOIN dwrdim_dw1.dwr_dim_company_d c ON s.ship_company_key = c.company_key
LEFT JOIN dwrdim_dw1.dwr_dim_supplier_d d ON s.supplier_key = d.supplier_key
WHERE actual_arrv_period_id = 202109
AND s.transp_demand_no='0FF7640001270MCHN01H'
;

前后两次执行结果

第一次执行 第二次执行


问题定位分析方位为执行如下语句

SELECT 
    no_tax_ind_amt,
    s.actual_arrv_period_id, s.transp_demand_no, s.transp_demand_no, -- PARTITION BY 列 + ORDER BY 列
    row_number() OVER(PARTITION BY s.actual_arrv_period_id, s.transp_demand_no ORDER BY s.transp_demand_no DESC) pck_rn,
    rank()       OVER(PARTITION BY s.actual_arrv_period_id, s.transp_demand_no ORDER BY s.transp_demand_no DESC) pck_rk
FROM fin_dwl_cbchnl.dwl_cbg_cst_tms_freigh_expen_f s
LEFT JOIN dwrdim_dw1.dwr_dim_company_d c ON s.ship_company_key = c.company_key
LEFT JOIN dwrdim_dw1.dwr_dim_supplier_d d ON s.supplier_key = d.supplier_key
WHERE actual_arrv_period_id = 202109
AND s.transp_demand_no='0FF7640001270MCHN01H'
;


可以看出相同的开窗逻辑下rank()值都1,而且所有记录中s.actual_arrv_period_id, s.transp_demand_no, s.transp_demand_no(即PARTITION BY 列 + ORDER BY 列)的值都是一样的

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。