数仓中典型的几种不下推语句整改案例

典型,几种,不下,语句,整改,案例 · 浏览次数 : 26

小编点评

# 生成内容时带简单的排版 生成内容时需要带简单的排版,以便方便人们理解和排版结果。以下是一些方法: 1. **使用标点符号:** 使用标点符号可以将结果排版在不同的格式中。例如,可以使用 `,` 和 `()` 来将结果排版在不同的格式中。 2. **使用标题:** 标题可以帮助人们快速了解结果的内容。例如,可以使用 `# 结果` 来添加标题。 3. **使用颜色:** 颜色可以帮助人们区分结果的内容。例如,可以使用 `红色` 来添加结果。 4. **使用表格:** 表格可以帮助人们查看结果的内容。例如,可以使用 `# 表格` 来添加表格。 5. **使用标签:**标签可以帮助人们将结果排版在不同的格式中。例如,可以使用 `#标签` 来添加标签。 6. **使用排版符号:**排版符号可以帮助人们将结果排版在不同的格式中。例如,可以使用 `,` 和 `()` 来将结果排版在不同的格式中。 7. **使用格式化工具:**格式化工具可以帮助人们格式化结果。例如,可以使用 `#格式化工具` 来添加格式化工具。 8. **使用排版符号:**排版符号可以帮助人们将结果排版在不同的格式中。例如,可以使用 `,` 和 `()` 来将结果排版在不同的格式中。 9. **使用标题和颜色:** 标题和颜色可以帮助人们快速了解结果的内容。例如,可以使用 `#标题和颜色` 来添加标题和颜色。 10. **使用表格和标签:** 表格和标签可以帮助人们查看结果的内容。例如,可以使用 `#表格和标签` 来添加表格和标签。 11. **使用排版符号:**排版符号可以帮助人们将结果排版在不同的格式中。例如,可以使用 `,` 和 `()` 来将结果排版在不同的格式中。 12. **使用排版工具:**排版工具可以帮助人们格式化结果。例如,可以使用 `#格式化工具` 来添加格式化工具。 13. **使用标题和颜色:** 标题和颜色可以帮助人们快速了解结果的内容。例如,可以使用 `#标题和颜色` 来添加标题和颜色。 14. **使用表格和标签:** 表格和标签可以帮助人们查看结果的内容。例如,可以使用 `#表格和标签` 来添加表格和标签。 15. **使用排版符号:**排版符号可以帮助人们将结果排版在不同的格式中。例如,可以使用 `,` 和 `()` 来将结果排版在不同的格式中。

正文

本文分享自华为云社区《GaussDB(DWS)性能调优:典型不下推语句整改案例》,作者: 譡里个檔 。

场景1:With-Recursive contains only values rte is not shippable

根因:递归语句的某个分支中没有FROM字句(只有 VALUES 或者类似 SELECT 1 这样的语句)

案例1:递归驱动分支没有FROM字句

原始语句

SELECT T.RPT_ITEM_ID, --报表项ID

T.RPT_ITEM_CODE,

T.USER_GROUP_CODE AS USER_GROUP_CODE --用户组

FROM BIF.BIF_RPT_ITEM_DEF_T T,

(WITH recursive cte AS (

SELECT DISTINCT TRIM(SUBSTR('' :: text, INSTR('', ',', 1, 1) + 1, INSTR('', ',', 1, 2) - INSTR('', ',', 1, 1) - 1)) AS cte_RPT_ITEM_CODE,

1 AS level

FROM (SELECT '') AS tb0



UNION ALL



SELECT DISTINCT TRIM(SUBSTR('' :: text, INSTR('', ',', 1, cte.level + 1) + 1, INSTR('', ',', 1, cte.level + 2) - INSTR('', ',', 1, cte.level + 1) - 1)),

cte.level + 1

FROM (SELECT '') AS tb0, cte

WHERE cte.level + 1 <= LENGTH('') - LENGTH(REPLACE('', ',', '')) - 1

)

SELECT

DISTINCT cte_RPT_ITEM_CODE AS RPT_ITEM_CODE

FROM cte

) T5

WHERE NVL(INSTR(T.RPT_ITEM_FREQUENCE, 'M'), 0) > 0

AND T.RPT_ITEM_CODE = NVL(T5.RPT_ITEM_CODE, T.RPT_ITEM_CODE)

AND T.RPT_ITEM_TYPE = 1 --是否是叶子报表项,1=是,0=否,基本报表项

AND T.ENABLE_FLAG = 1

AND T.VERSION = '202308' --使用快照,增加条件限制

ORDER BY T.RPT_ITEM_ID

改写语句

SELECT T.RPT_ITEM_ID, --报表项ID

T.RPT_ITEM_CODE,

T.USER_GROUP_CODE AS USER_GROUP_CODE --用户组

FROM BIF.BIF_RPT_ITEM_DEF_T T,

(WITH recursive cte AS (

SELECT DISTINCT TRIM(SUBSTR('' :: text, INSTR('', ',', 1, 1) + 1, INSTR('', ',', 1, 2) - INSTR('', ',', 1, 1) - 1)) AS cte_RPT_ITEM_CODE,

1 AS level

FROM (SELECT '') AS tb0



UNION ALL



SELECT DISTINCT TRIM(SUBSTR('' :: text, INSTR('', ',', 1, cte.level + 1) + 1, INSTR('', ',', 1, cte.level + 2) - INSTR('', ',', 1, cte.level + 1) - 1)),

cte.level + 1

FROM (SELECT '') AS tb0, cte

WHERE cte.level + 1 <= LENGTH('') - LENGTH(REPLACE('', ',', '')) - 1

)

SELECT

DISTINCT cte_RPT_ITEM_CODE AS RPT_ITEM_CODE

FROM cte

) T5

WHERE NVL(INSTR(T.RPT_ITEM_FREQUENCE, 'M'), 0) > 0

AND T.RPT_ITEM_CODE = NVL(T5.RPT_ITEM_CODE, T.RPT_ITEM_CODE)

AND T.RPT_ITEM_TYPE = 1 --是否是叶子报表项,1=是,0=否,基本报表项

AND T.ENABLE_FLAG = 1

AND T.VERSION = '202308' --使用快照,增加条件限制

ORDER BY T.RPT_ITEM_ID

修改点比对

cke_163.png

案例2:递归驱动分支没有FROM字句

原始语句

SELECT A.DYNM_COMP_ID,

DECODE(B.LINE_NO, 1, '202308', A.VERSION)

FROM BIF.BIF_DYNM_COMP_SOU_TBL_V A,

(WITH recursive cte AS (

SELECT 1 AS level

UNION ALL

SELECT cte.level + 1

FROM cte

WHERE cte.level + 1 < 3

)

SELECT

level as LINE_NO

FROM cte

) B

WHERE EXISTS (SELECT 1

FROM BIF.BIF_RPT_ITEM_DEF_MV RPT,

BIF.BIF_PUB_SUBJECT_AREA_T SBJ,

BIF.BIF_SNAPSHORT_SUBJECT_V TYP

WHERE A.DYNM_COMP_ID = RPT.DYNM_COMP_ID

AND RPT.VERSION = 'current'

AND RPT.SUBJECT_AREA_ID = SBJ.SUBJECT_AREA_ID

AND SBJ.SUBJECT_AREA_CODE =TYP.SUBJECT_CODE

AND TYP.SUBJECT_TYPE ='TAX')

AND A.VERSION = 'current'

改写语句

SELECT A.DYNM_COMP_ID,

DECODE(B.LINE_NO, 1, '202308', A.VERSION)

FROM BIF.BIF_DYNM_COMP_SOU_TBL_V A,

(SELECT

*

FROM generate_series(1, 2) AS cte(LINE_NO)

) B

WHERE EXISTS (SELECT 1

FROM BIF.BIF_RPT_ITEM_DEF_MV RPT,

BIF.BIF_PUB_SUBJECT_AREA_T SBJ,

BIF.BIF_SNAPSHORT_SUBJECT_V TYP

WHERE A.DYNM_COMP_ID = RPT.DYNM_COMP_ID

AND RPT.VERSION = 'current'

AND RPT.SUBJECT_AREA_ID = SBJ.SUBJECT_AREA_ID

AND SBJ.SUBJECT_AREA_CODE =TYP.SUBJECT_CODE

AND TYP.SUBJECT_TYPE ='TAX')

AND A.VERSION = 'current'

修改点比对

cke_164.png

案例3:递归驱动分支是VALUES字句

原始语句

WITH RECURSIVE t(n) AS (

VALUES (1)

UNION ALL

SELECT

n+1

FROM t

WHERE n < (SELECT MAX(LENGTH(COMP_CODE)-LENGTH(REPLACE(COMP_CODE,',','')))+1 MAX_TOKENS

FROM (SELECT DEPT_CODE,

to_char(APPLICABLE_GEO_PC_CODE) COMP_CODE

FROM SDIHR.MDM_CDM_DEPT_ACT_INFO_T_3600)

)

)

SELECT n AS LVL FROM t

改写语句

WITH RECURSIVE t(n) AS (

SELECT * FROM generate_series(1, 1)

UNION ALL

SELECT

n+1

FROM t

WHERE n < (SELECT MAX(LENGTH(COMP_CODE)-LENGTH(REPLACE(COMP_CODE,',','')))+1 MAX_TOKENS

FROM (SELECT DEPT_CODE,

to_char(APPLICABLE_GEO_PC_CODE) COMP_CODE

FROM SDIHR.MDM_CDM_DEPT_ACT_INFO_T_3600)

)

)

SELECT n AS LVL FROM t

修改点比对

cke_165.png

案例4:递归驱动分支是VALUES字句

原始语句

WITH RECURSIVE t(n) AS (

VALUES (1)

UNION ALL

SELECT

n+1

FROM t

WHERE n < (SELECT MAX(LENGTH(COMP_CODE)-LENGTH(REPLACE(COMP_CODE,',','')))+1 MAX_TOKENS

FROM (SELECT DEPT_CODE,

to_char(APPLICABLE_GEO_PC_CODE) COMP_CODE

FROM SDIHR.MDM_CDM_DEPT_ACT_INFO_T_3600))

)

SELECT n AS LVL FROM t

改写语句

SELECT

*

FROM generate_series(1, (SELECT MAX(LENGTH(COMP_CODE)-LENGTH(REPLACE(COMP_CODE,',','')))+1 MAX_TOKENS

FROM (SELECT DEPT_CODE,

to_char(APPLICABLE_GEO_PC_CODE) COMP_CODE

FROM SDIHR.MDM_CDM_DEPT_ACT_INFO_T_3600))

) AS t(lvl)

修改点比对

cke_166.png

场景2:With-Recursive contains system table is not shippable

根因:递归语句的某个分支中没有FROM字句中只用系统表或者系统视图(DUAL也被视为系统视图)

案例1:递归驱动分支是FROM DUAL查询

原始语句

WITH recursive cte AS (

SELECT

TO_DATE(201701, 'YYYYMM') as level ,TO_DATE(20170131, 'YYYYMMDD') LASTDAY

FROM dual

UNION ALL

SELECT

ADD_MONTHS(cte.LEVEL, 1) AS PERIOD,

LAST_DAY(ADD_MONTHS(cte.LEVEL, 1)) AS LASTDAY

FROM cte WHERE cte.LEVEL <=SYSDATE

)

SELECT

TO_CHAR(cte.level,'YYYYMMDD') AS PERIOD , cte.LASTDAY

FROM cte

WHERE TO_CHAR(cte.level,'YYYYMMDD')<= TO_CHAR(SYSDATE,'YYYYMMDD')

改写语句

WITH recursive cte AS (

SELECT

TO_DATE(201701, 'YYYYMM') as level ,TO_DATE(20170131, 'YYYYMMDD') LASTDAY

FROM dual

UNION ALL

SELECT

ADD_MONTHS(cte.LEVEL, 1) AS PERIOD,

LAST_DAY(ADD_MONTHS(cte.LEVEL, 1)) AS LASTDAY

FROM cte WHERE cte.LEVEL <=SYSDATE

)

SELECT

TO_CHAR(cte.level,'YYYYMMDD') AS PERIOD , cte.LASTDAY

FROM cte

WHERE TO_CHAR(cte.level,'YYYYMMDD')<= TO_CHAR(SYSDATE,'YYYYMMDD')

修改点对比

cke_167.png

场景3:SubPlan exec on CN can't be shipped

根因:某个子查询语句只能在CN上执行,通常是这个子查询有不下推因素,比如有系统表、系统视图调用,或者存在不下推函数等

案例1:子查询中系统表/系统视图查询

原始语句

WITH error_log AS NOT MATERIALIZED (

SELECT

upper(log_column_name) AS log_column_name,

log_error_code,

s.char_length AS data_length,

s.data_type,s.nullable

FROM (SELECT

distinct

unnest(string_to_array(bad_log_column_name,',')) AS log_column_name,

unnest(string_to_array(bad_log_error_code,',')) AS log_error_code

FROM stgltc.BAD_cfs_inv_invoice_ad_2500

) T,

(SELECT * FROM user_tab_columns WHERE table_name=lower('dlt_cfs_inv_invoice_ad_2500')) S

WHERE upper(T.log_column_name)=upper(S.column_name)

)

SELECT

CASE WHEN upper('ACTIVITY_NAME') IN (SELECT log_column_name FROM error_log WHERE data_type IN ('varchar','char','character','nchar','character varying','varchar2','nvarchar2','clob','text') AND log_error_code='22001'/*字符超长*/)

THEN SUBSTRB(ACTIVITY_NAME,0,(SELECT distinct DATA_LENGTH FROM error_log WHERE upper(log_column_name)=upper('ACTIVITY_NAME')))

ELSE ACTIVITY_NAME

END AS ACTIVITY_NAME,

CASE WHEN upper('ADJUSTMENT_ID') IN (SELECT log_column_name FROM error_log WHERE data_type IN ('varchar','char','character','nchar','character varying','varchar2','nvarchar2','clob','text') AND log_error_code='22001'/*字符超长*/)

THEN SUBSTRB(ADJUSTMENT_ID,0,(SELECT distinct DATA_LENGTH FROM error_log WHERE upper(log_column_name)=upper('ADJUSTMENT_ID')))

ELSE ADJUSTMENT_ID

END AS ADJUSTMENT_ID

FROM stgltc.BAD_cfs_inv_invoice_ad_2500

改写语句

-- 识别不下推的子查询为WITH error_log字句中的

-- SELECT * FROM user_tab_columns WHERE table_name=lower('dlt_cfs_inv_invoice_ad_2500')

--

-- 因为这部分为系统表查询,无论如何都不能下推,所以此处把这部分结果转储到一个中间表中

-- 中间表创建成行存表

CREATE TEMP TABLE s WITH(orientation=row) DISTRIBUTE BY ROUNDROBIN AS

SELECT * FROM user_tab_columns WHERE table_name=lower('dlt_cfs_inv_invoice_ad_2500')

-- 因为整个查询涉及到的表都是列存表,之后前面创建的临时表s为行存表

-- 所以此处加一个强制走向量化的hint

WITH error_log AS NOT MATERIALIZED (

SELECT

upper(log_column_name) AS log_column_name,

log_error_code,

s.char_length AS data_length,

s.data_type,s.nullable

FROM (SELECT

distinct

unnest(string_to_array(bad_log_column_name,',')) AS log_column_name,

unnest(string_to_array(bad_log_error_code,',')) AS log_error_code

FROM stgltc.bad_cfs_inv_invoice_ad_2500

) T,

pg_temp.S

WHERE upper(T.log_column_name)=upper(S.column_name)

)

SELECT /*+ set global(enable_force_vector_engine on)*/

CASE WHEN upper('ACTIVITY_NAME') IN (SELECT log_column_name FROM error_log WHERE data_type IN ('varchar','char','character','nchar','character varying','varchar2','nvarchar2','clob','text') AND log_error_code='22001'/*字符超长*/)

THEN SUBSTRB(ACTIVITY_NAME,0,(SELECT distinct DATA_LENGTH FROM error_log WHERE upper(log_column_name)=upper('ACTIVITY_NAME')))

ELSE ACTIVITY_NAME

END AS ACTIVITY_NAME,

CASE WHEN upper('ADJUSTMENT_ID') IN (SELECT log_column_name FROM error_log WHERE data_type IN ('varchar','char','character','nchar','character varying','varchar2','nvarchar2','clob','text') AND log_error_code='22001'/*字符超长*/)

THEN SUBSTRB(ADJUSTMENT_ID,0,(SELECT distinct DATA_LENGTH FROM error_log WHERE upper(log_column_name)=upper('ADJUSTMENT_ID')))

ELSE ADJUSTMENT_ID

END AS ADJUSTMENT_ID

FROM stgltc.bad_cfs_inv_invoice_ad_2500

修改点对比

cke_168.png

场景4:Type of Record in TargetList can not be shipped

根因:输出列中存在record类型,这种类型的不下推一般是不会体现在最外层的输出列上,一般这类报错有两个场景

1.SQL书写逻辑错误,导致输出列上出现了(...)形式的输出列

2.SQL业务逻辑正确, 这种场景需要了解业务含义,把record字段强转为text类型,然后再使用record字段的地方做特殊适配

案例1:输出列书写错误,出现(...)形式的输出列

原始语句

SELECT

d.id,

coalesce(d.period, 'snull') AS period,

(d.plan_unit_code, 'snull') AS plan_unit_code,

coalesce(d.product_type_model, 'snull') AS product_type_model,

coalesce(d.revision, 'snull') AS revision,

d.start_date

FROM (SELECT *

FROM cdcscm.cdc_mp_d_forecast_t_6120 t

WHERE t.cdc_timestamp > to_date('2023-07-06 00:00:00', 'yyyy-mm-dd hh24:mi:ss') - 7

AND t.cdc_timestamp < to_date('2023-08-08 00:00:00', 'yyyy-mm-dd hh24:mi:ss')

) t1,

sdiscm.mp_d_forecast_t_6120 d

WHERE (t1.audit_op_type = 'delete' AND t1.audit_op_option = 'before')

AND d.id = t1.id

改写语句

SELECT

d.id,

coalesce(d.period, 'snull') AS period,

coalesce(d.plan_unit_code, 'snull') AS plan_unit_code,

coalesce(d.product_type_model, 'snull') AS product_type_model,

coalesce(d.revision, 'snull') AS revision,

d.start_date

FROM (SELECT *

FROM cdcscm.cdc_mp_d_forecast_t_6120 t

WHERE t.cdc_timestamp > to_date('2023-07-06 00:00:00', 'yyyy-mm-dd hh24:mi:ss') - 7

AND t.cdc_timestamp < to_date('2023-08-08 00:00:00', 'yyyy-mm-dd hh24:mi:ss')

) t1,

sdiscm.mp_d_forecast_t_6120 d

WHERE (t1.audit_op_type = 'delete' AND t1.audit_op_option = 'before')

AND d.id = t1.id

修改点对比

cke_169.png

备注:改写前后语句不等价,不等价的原因是因为原始SQL书写有问题,正确的写法是就是coalesce(d.plan_unit_code, 'snull') AS plan_unit_code。

点击关注,第一时间了解华为云新鲜技术~

与数仓中典型的几种不下推语句整改案例相似的内容:

数仓中典型的几种不下推语句整改案例

本文为大家讲解4个DWS常见不下推语句整改场景中的相关案例。

解读数仓中的数据对象及相关关系

摘要:为实现不同的功能,GaussDB(DWS)提供了不同的数据对象类型,包括索引、行存表、列存表及其辅助表等。这些数据对象在特定的条件下实现不同的功能,为数据库的快速高效提供了保证,本文对部分数据对象进行介绍。 本文分享自华为云社区《GaussDB(DWS)之数据对象及相互关系总结》,作者:我的橘

详解数仓中sequence的应用场景及优化

摘要:本文简单介绍sequence的使用场景及如何修改sequence的cache值提高性能。 本文分享自华为云社区《GaussDB(DWS)关于sequence的那些事》,作者:Arrow0lf 。 什么是sequence sequence,也称作序列,是用来产生唯一整数的数据库对象。序列的值按照

对比分析数仓中行列存的特性

摘要:行存表示了一种数据的存储方式,是最传统的一种存储方式。 本文分享自华为云社区《【玩转PB级数仓GaussDB(DWS)】行列存对比的一些事》,作者:sevenjiang。 行存表示了一种数据的存储方式,是最传统的一种存储方式。对于GaussDB(DWS)来说可以认为其表示存储引擎的基础实现,在

大数据 - DWM层 业务实现

DWM 建表,需要看 DWS 需求。 DWS 来自维度(访客、商品、地区、关键词),为了出最终的指标 ADS 需求指标 DWT 为什么实时数仓没有DWT,因为它是历史的聚集,累积结果,实时数仓中不需要 DWD 不需要加工 DWM 需要加工的数据 统计主题 需求指标【ADS】输出方式计算来源来源层级

【数仓运维实践】关于GaussDB(DWS)单SQL磁盘空间管控

摘要:本文主要讲解数仓运维中遇到单SQL磁盘空间管控问题的解析和方案。 本文分享自华为云社区《GaussDB(DWS)运维 -- 单SQL磁盘空间管控》,作者: 譡里个檔。 【问题描述】 执行部分SQL语句时出现如下报错信息(具体数值可能因为配置有差异),本文针对根因和场景触发场景,确定触发此类问题

数仓在线运维:如何进行在线增删CN?

摘要:集群运行过程中,根据集群的综合负载和业务接入情况进行分析:增加CN可以适当降低CPU消耗,增大接入连接数,分散CN节点业务压力,根据实际情况来识别是否要增加CN,如果是提升集群容量和扩展比能力,建议进行扩容操作。 本文分享自华为云社区《【玩转PB级数仓GaussDB(DWS)】在线运维-在线增

教你如何进行数仓字符串、二进制、十六进制互转

现网中遇到很多小伙伴不清楚字符串与进制之间的转换方法,其实在GaussDB(DWS)中,进制转换是非常方便的。

数仓性能调优:大宽表关联MERGE性能优化

摘要:本文主要为大家讲解在数仓性能调优过程中,关于大宽表关联MERGE性能优化过程。 本文分享自华为云社区《GaussDB(DWS)性能调优:大宽表关联MERGE性能优化》,作者:譡里个檔。 【业务背景】 如下MERGE语句执行耗时长达2034s MERGE INTO sdifin.hah_ae_l

带你走进数仓大集群内幕丨详解关于作业hang及残留问题定位

测试过程中,我们会遇到这样一种情况,我的作业都执行很久了,为啥还不结束,是不是作业hang掉了?