GaussDB(DWS)性能调优:性能问题闭环总结(一)——关联慢
主要从四个方面来分析,
一、关联慢
1、关联倾斜优化
业务问题
如下图所示,SQL执行性能瓶颈在于关联(发生数据倾斜),导致执行时间达到16min(该案例并非去HANA过程中发生的,而是从别处拿来讲解的案例)
分析思路
关联过程中,因为**关联条件中不包含表的分布键,可能会发生表关于关联条件重分布这一过程(也有可能直接广播,优化器会根据估算代价决定)。因此,会产生这样一种情况:关联条件中某个字段重复值过多,进而导致重分布时,数据分布产生倾斜(不同DN上数据量相差10% 即判定为数据倾斜)**,
关联倾斜的后果是:某个DN会因为数据量过大而成为语句执行的性能瓶颈
解决措施:
- 找出关联条件中重复值较多的那个字段以及重复值
重复值判断方法:
select count(1),report_item_id from fin_dmr_ebg.dm_ebg_reg_kpi_sum_w_f
where 过滤条件
group by 2
order by 1 desc
- 在当前层(即发生关联这一层查询中)使用hint: /+skew(表名(字段名)(重复值))/
具体使用方法可以看 https://support.huaweicloud.com/intl/zh-cn/performance-dws/dws_10_0029.html
优化后,如下图所示,从执行计划中看出,运行倾斜问题得到了缓解
这两个问题解决后,语句执行性能变好,由992.835s变为173.7s,
小结
DWS中一般默认将skew_option设置为normal(采用激进策略。对于不确定是否出现倾斜的场景,认为存在倾斜,并进行相应优化),因此,常规情况下,优化器能较好地避免数据倾斜情况,但不排除一些特殊情况导致优化器并未识别到。
2、调整关联顺序以避免关联倾斜
业务问题
该SQL语句执行时存在数据倾斜的问题,影响语句执行效率
分析思路
首先,查看语句执行计划,计划信息的SQL Diagnostic Information显示id=4那一层DN上最大数据20w,最小数据量5000+,证明发生了数据倾斜的问题,然后观察上边那一层出现Join(关联),证明是关联时数据倾斜。
然后,针对该SQL这一点进行优化,一般来说,DWS优化器能够识别倾斜并进行相应优化(例如图中的PART … PART …),但可能也无法解决问题。
此时,可以修改关联顺序,先和表geo关联,因为数据倾斜可能是在关联其他表过程中发生的。
在DWS中,引入guc参数leading,来指定join顺序,该参数有两种使用方式:
- leading(join_table_list) 仅指定join顺序,不指定内外表顺序
- leading((join_table_list)) 同时指定join顺序和内外表顺序,内外表顺序仅在最外层生效。如leading((a b)),则表a为外表,表b为内表。
使用过程中需要注意:
- list中的表必须在当前层或提升的子查询中存在。
- list中的表在当前层或提升的子查询中必须是唯一的。如果不唯一,需要使用不同的别名进行区分。
- 同一个表只能在list里出现一次。
- 如果表存在别名,则list中的表需要使用别名。
言归正传,让基表ship先和geo关联,再和大表dtl关联,最后再和表org关联(因为org在SQL语句中仅和表dtl有关联关系),此时利用hint来实现这一优化过程,hint需要加在当前层(含有这些表关联的那一层)
/*+ leading((ship geo) dtl)*/
该SQL经过优化后,执行时间降低了800ms左右,其执行计划如下图所示:
基表先和小表geo关联,缓解了原始SQL中存在数据倾斜问题,同时也降低了大数据量的REDISTRIBUTE和关联。
小结
SQL语句执行过程中,关联过程中(尤其是存在多重关联),如果某层关联能够减少大部分数据量,要利用hint将该层关联提到其能达到的最底层,以减少关联数据量。
3、避免Nest Loop算子引起的性能瓶颈
业务问题
SQL语句执行性能差,语句计划中存在Nest Loop算子引发性能瓶颈
分析思路
DWS中,Hash Join 的性能一般要优于 Nest Loop,因此,发现SQL语句执行慢并且执行计划中存在Nest Loop算子时通常要进行规避,一般导致Nest Loop出现的情况有三种:
两表无关联条件(笛卡尔积)
该情况比较简单,如果关联中仅有这两张表则无法优化,只能走Nest Loop算子;若存在多张表,则可以通过调整关联顺序,以避免无关联条件的情况,若无法避免则也只能走Nest Loop算子。
优化器走Index Scan+Nest Loop
上图因为性能问题,无法打出performance执行计划,从verbose执行计划中看到存在Index Scan+Nest Loop,此时,大致可以判断问题出在这里,原因是:优化器错误估算表的行数,导致Index Scan查询时因为频繁利用索引导致开销增大,效果不如全表扫描
此时可以利用hint来进行避免
设置 hint /*+set [global](enable_index_nestloop off)*/ (若加在最外层,可以使用global;否则需要去掉global,不然hint无法生效)
设置全局参数 set enable_index_nestloop = off; (先执行该语句,再执行原始SQL)
从上图中可以看出,走全表扫描+Hash Join的效率远远优于 Index Scan+Nest Loop,SQL语句3s+就执行完毕。
不等值关联
由于Hash Join仅支持等值关联的情况,因此若SQL语句中存在不等值关联,则优化器只会执行Nest Loop算子,不等值关联有多种情况,本文先介绍去HANA优化过程中遇到的两种:
(1)or不等值关联改写
从上图中可以看出,该语句执行过程中的性能瓶颈在于Nest Loop算子,利用hint或全局参数无法避免,因为SQL语句中存在or不等值关联
SELECT
t2.PARTNER_CHANNEL_CODE AS CHANNEL_ID
,t1.COUNTRY_CODE
,t1.BRAND
,t2.CHANNEL_ID AS CHANNEL_ID2
FROM PRIMARY_KEY_BEFOR t1
LEFT JOIN
(
SELECT
PARTNER_CHANNEL_CODE
,CUST_ACCOUNT_NUM||'/'||CHANNEL_MODE_CODE AS CHANNEL_ID
FROM BI_DASHBOARD.RPT_PSI_CHANNEL_CUSTOMER_D T
GROUP BY
PARTNER_CHANNEL_CODE
,CUST_ACCOUNT_NUM||'/'||CHANNEL_MODE_CODE
)t2
ON (t2.CHANNEL_ID = t1.CHANNEL_ID AND t1.TYPE='DR')
OR (t2.PARTNER_CHANNEL_CODE = t1.CHANNEL_ID AND t1.TYPE='ALL' )
GROUP BY t2.PARTNER_CHANNEL_CODE
,t1.COUNTRY_CODE
,t1.BRAND
,t2.CHANNEL_ID
利用 UNION ALL(如果要求结果集去重的话使用 UNION),修改后SQL如下所示:
SELECT
t2.PARTNER_CHANNEL_CODE AS CHANNEL_ID
,t1.COUNTRY_CODE
,t1.BRAND
,t2.CHANNEL_ID AS CHANNEL_ID2
FROM PRIMARY_KEY_BEFOR t1
LEFT JOIN
(
SELECT
PARTNER_CHANNEL_CODE
,CUST_ACCOUNT_NUM||'/'||CHANNEL_MODE_CODE AS CHANNEL_ID
FROM BI_DASHBOARD.RPT_PSI_CHANNEL_CUSTOMER_D T
GROUP BY
PARTNER_CHANNEL_CODE
,CUST_ACCOUNT_NUM||'/'||CHANNEL_MODE_CODE
)t2
ON (t2.CHANNEL_ID = t1.CHANNEL_ID AND t1.TYPE='DR')
GROUP BY t2.PARTNER_CHANNEL_CODE
,t1.COUNTRY_CODE
,t1.BRAND
,t2.CHANNEL_ID
UNION
SELECT
t2.PARTNER_CHANNEL_CODE AS CHANNEL_ID
,t1.COUNTRY_CODE
,t1.BRAND
,t2.CHANNEL_ID AS CHANNEL_ID2
FROM PRIMARY_KEY_BEFOR t1
LEFT JOIN
(
SELECT
PARTNER_CHANNEL_CODE
,CUST_ACCOUNT_NUM||'/'||CHANNEL_MODE_CODE AS CHANNEL_ID
FROM BI_DASHBOARD.RPT_PSI_CHANNEL_CUSTOMER_D T
GROUP BY
PARTNER_CHANNEL_CODE
,CUST_ACCOUNT_NUM||'/'||CHANNEL_MODE_CODE
)t2
ON (t2.PARTNER_CHANNEL_CODE = t1.CHANNEL_ID AND t1.TYPE='ALL' )
GROUP BY t2.PARTNER_CHANNEL_CODE
,t1.COUNTRY_CODE
,t1.BRAND
,t2.CHANNEL_ID
UNION (ALL)补充
- union:
UNION用于合并多个查询结果,并且会自动去除重复的行,确保最终的结果集中没有重复数据。这种去重操作的好处是我们可以获得干净、唯一的结果集,但同时也带来了性能开销。去重操作需要比较和过滤结果集中的每一行,这可能会导致较大的性能消耗。因此,在使用UNION操作符时,需要权衡结果集的唯一性和性能开销之间的折衷。 - union all:
UNION ALL也用于合并多个查询结果,但是,它不进行去重操作。这意味着UNION ALL返回的结果集可能包含重复的行。然而,由于没有去重的开销,UNION ALL的性能通常比UNION更好。如果我们已经确保结果集中没有重复行,或者我们不关心结果集中的重复行,那么使用UNION ALL可以获得更好的查询性能。 - 两者区别
结果集:UNION会在结果集中去重
结果集顺序:UNION会在最终结果集进行排序,UNION ALL不会进行排序,结果集顺序由各个子查询顺序决定
性能:由于UNION会去重和排序,因此UNION ALL的性能要优于UNION。
从整改后的SQL执行计划中可以看出来,去掉Nest Loop算子后,SQL执行时间降为500ms左右,大大优化了语句执行性能
(2) between不等值关联改写
该SQL的性能瓶颈同样在于Nest Loop算子,查看其原始SQL语句
SELECT
'W' AS DIMENSION,
ECODE('W','W',LEFT(TO_CHAR(P.PERIOD_ID),4)||'WK' || LPAD(P.WEEK_NO, 2, '0')||date_format(P. PERIOD_ST_DATE, '%Y%m%d'),'M',LEFT(TO_CHAR(P.PERIOD_ID),4)||date_format(ADDDATE(P.PERIOD_ST_DATE,3),'%m'),'Q',LEFT(date_format(QD.PERIOD_ST_DATE,'%Y%m%d'),4)||'Q' || quarter(QD.PERIOD_ST_DATE),'Y',LEFT(TO_CHAR(P.PERIOD_ID),4)) AS "TIME",
SUM(AATP) AS AATP, -- AATP
SUM(FCST_QTY) AS FCST_QTY, -- 要货预测
SUM(SHIPPED_QTY) AS SHIPPED_QTY, -- 已发货
SUM(SALES_RPD_QTY) AS SALES_RPD_QTY, -- 代表处DFS SO RPD数量
SUM(SALES_EPD_QTY) AS SALES_EPD_QTY, -- 代表处DFS SO EPD数量
SUM(PRESO_RPD_QTY) AS PRESO_RPD_QTY,-- RPD(PreSO)
SUM(PRESO_EPD_QTY) AS PRESO_EPD_QTY,-- EPD(PreSO)
SUM(NET_RPD_QTY) AS NET_RPD_QTY,
SUM(NET_EPD_QTY) AS NET_EPD_QTY,
SUM(CURRENT_TIME_LEFT_AATP) AS CURRENT_TIME_LEFT_AATP, -- 当周剩余AATP:AATP-已发货-DFS SO EPD
SUM(EPD_MORE_QTY) AS EPD_MORE_QTY
FROM (SELECT PD.PERIOD_ID,PD.PERIOD_ST_DATE,PD.WEEK_NO,PD.PERIOD_END_DATE FROM DMISC.DM_DIM_CBG_PERIOD_D PD WHERE PD.PERIOD_TYPE='D' AND PD.DEL_FLAG = 'N') D
LEFT JOIN (......)
ON D.PERIOD_ID = CAST(date_format(DFS_DATE,'%Y%m%d') as bigint)
LEFT JOIN (SELECT PD.PERIOD_ID,PD.PERIOD_ST_DATE,PD.WEEK_NO,PD.PERIOD_END_DATE FROM DMISC.DM_DIM_CBG_PERIOD_D PD WHERE PD.PERIOD_TYPE='W' AND PD.DEL_FLAG = 'N') P
ON D.PERIOD_ID BETWEEN CAST(date_format(P.PERIOD_ST_DATE,'%Y%m%d') as bigint) AND CAST(date_format(P.PERIOD_END_DATE,'%Y%m%d') as bigint)
LEFT JOIN (SELECT PD.PERIOD_ST_DATE,PD.PERIOD_END_DATE FROM DMISC.DM_DIM_CBG_PERIOD_D PD WHERE PD.PERIOD_TYPE='Q' AND PD.DEL_FLAG = 'N') QD
ON D.PERIOD_ID BETWEEN CAST(date_format(QD.PERIOD_ST_DATE,'%Y%m%d') as bigint)AND CAST(date_format(QD.PERIOD_END_DATE,'%Y%m%d') as bigint)
WHERE D.PERIOD_ID BETWEEN CAST(date_format('2023-01-01','%Y%m%d') as bigint) AND CAST(date_format('2023-08-01','%Y%m%d') as bigint)
GROUP BY 1,2
原始SQL语句中,存在between非等值关联,因此,从between中的值入手进行分析,该语句语义是,从DMISC.DM_DIM_CBG_PERIOD_D表中取出PERIOD_TYPE = ‘D’(Day),然后跟从该表取出的PERIOD_TYPE = ‘W’(Week)进行关联,最后和从该表取出的PERIOD_TYPE = ‘Q’(Quarter)进行关联,原始SQL是利用between字段中的开始日期与结束日期进行关联。查看该表中的所有字段,发现可以换一种思路,PERIOD_TYPE = 'D’情况下有非空字段year、qtr_no(季度)、month_no、week_no(周),PERIOD_TYPE = 'W’情况下有非空字段year、week_no(周),PERIOD_TYPE = 'Q’情况下有非空字段year、qtr_no(季度),此时可以利用year、week_no/qtr_no来进行关联。
优化后的SQL如下所示:
FROM (SELECT PD.YEAR,PD.PERIOD_ID,PD.PERIOD_ST_DATE,PD.WEEK_NO,PD.PERIOD_END_DATE FROM DMISC.DM_DIM_CBG_PERIOD_D PD WHERE PD.PERIOD_TYPE='D' AND PD.DEL_FLAG = 'N') D
LEFT JOIN (......)
ON D.PERIOD_ID = CAST(date_format(DFS_DATE,'%Y%m%d') as bigint)
LEFT JOIN (SELECT * FROM DMISC.DM_DIM_CBG_PERIOD_D PD WHERE PD.PERIOD_TYPE='W' AND PD.DEL_FLAG = 'N') P ON D.year = P.year and D.week_no = P.week_no
LEFT JOIN (SELECT * FROM DMISC.DM_DIM_CBG_PERIOD_D PD WHERE PD.PERIOD_TYPE='Q' AND PD.DEL_FLAG = 'N') QD ON D.year = QD.year and D.week_no = QD.qtr_no
WHERE D.PERIOD_ID BETWEEN CAST(date_format('2023-01-01','%Y%m%d') as bigint) AND CAST(date_format('2023-08-01','%Y%m%d') as bigint)
GROUP BY 1,2
从上图优化后的SQL执行计划中可以看到,耗时降低为900ms+
小结
DWS中通常会避免使用Nest Loop算子,除非出现毫无关联条件的情况(不常出现),遇到Nest Loop算子时先采用hint或全局参数进行规避,如果未生效,则证明SQL语句存在非等值关联,要对SQL语句的关联逻辑进行整改
4、避免关联发散引起的性能瓶颈
业务问题
如下图所示,SQL语句执行过程中,存在关联发散导致结果集数量过大,同时,要对这么大体量的数据进行排序去重,两者效果叠加,语句执行时间达到了65s+。
存在数据发散的SQL语句如下所示
SELECT D.LV1_PROD_LIST_EN_NAME AS LV1_RPOD_EN_NAME,
F.EXTERNAL_NAME AS EXTERNAL_NAME,
D.LV1_PROD_LIST_CODE AS LV1_PROD_LIST_CODE,
SUM(CASE WHEN F.PERIOD_ID=20230510 THEN F.SO_QTY ELSE NULL END) AS SO_QTY_ACT1,
SUM(CASE WHEN F.PERIOD_ID=20230509 THEN F.SO_QTY ELSE NULL END) AS SO_QTY_ACT2,
SUM(CASE WHEN F.PERIOD_ID=20230508 THEN F.SO_QTY ELSE NULL END) AS SO_QTY_ACT3,
SUM(CASE WHEN F.PERIOD_ID=20230510 THEN F.SO_QTY_LAST ELSE NULL END) AS SO_QTY_LAST,
SUM(CASE WHEN F.PERIOD_ID=20230510 THEN F.SO_QTY_WTD ELSE NULL END) AS SO_QTY_WTD1,
SUM(CASE WHEN F.PERIOD_ID=20230507 THEN F.SO_QTY_WTD ELSE NULL END) AS SO_QTY_WTD2,
SUM(CASE WHEN F.PERIOD_ID=20230430 THEN F.SO_QTY_WTD ELSE NULL END) AS SO_QTY_WTD3,
SUM(CASE WHEN F.PERIOD_ID=20230510 THEN F.SO_QTY_WTD_LAST ELSE NULL END) AS SO_QTY_WTD_LAST,
SUM(CASE WHEN F.PERIOD_ID=20230510 THEN F.SO_QTY_MTD ELSE NULL END) AS SO_QTY_MTD1,
SUM(CASE WHEN F.PERIOD_ID=20230430 THEN F.SO_QTY_MTD ELSE NULL END) AS SO_QTY_MTD2,
SUM(CASE WHEN F.PERIOD_ID=20230331 THEN F.SO_QTY_MTD ELSE NULL END) AS SO_QTY_MTD3,
SUM(CASE WHEN F.PERIOD_ID=20230510 THEN F.SO_QTY_MTD_LAST ELSE NULL END) AS SO_QTY_MTD_LAST
FROM BI_DASHBOARD.DM_MSS_OS_PC_AREA_SO_COL_D_F F
INNER JOIN BI_DASHBOARD.DM_MSS_ITEM_PRODUCT_D D ON F.EXTERNAL_NAME = D.MKT_NAME AND D.LV1_PROD_LIST_FLAG = 'MH'
WHERE 1=1
AND F.PERIOD_ID IN (20230510,20230509,20230508,20230507,20230430,20230430,20230331)
AND F.EXTERNAL_NAME IN ( SELECT MKT_NAME EXTERNAL_NAME
FROM BI_DASHBOARD.DM_MSS_ITEM_PRODUCT_D PRD
WHERE PRD.COMPANY_BRAND =any(array[string_to_array('HUAWEI,HONER',',')])
AND MKT_NAME<>'SNULL' GROUP BY MKT_NAME)
AND (F.LARGE_AREA_CODE IN ('') OR '' IS NULL OR ''= '')
AND (F.SMALL_AREA_CODE IN ('') OR '' IS NULL OR ''= '')
AND F.ECOSYSTEM = 'AG'
AND F.SALES_FLAG = '1'
AND F.ORG_CODE=F.SIGN_COUNTRY_PROVINCE_CODE
GROUP BY F.EXTERNAL_NAME,D.LV1_PROD_LIST_EN_NAME,D.LV1_PROD_LIST_CODE
分析思路
从图中标记的地方可以看出,SQL在执行过程中,F表与D表关联时存在严重的数据发散现象,同时,sort排序处处理大数据量的结果集也导致执行时间过长。
对原始SQL进行分析,该SQL语义是:对F表进行过滤,然后与D表进行关联,取某几个固定年份的数据求和,查询最后输出的f表的值仅为EXTERNAL_NAME 并且关联条件也是EXTERNAL_NAME,此时,可以针对该SQL进行改写,可以先对f表的EXTERNAL_NAME值进行去重再关联,从而降低窗口函数中排序时的数据量,以提高语句执行效率。
改写后的SQL如下所示:
SELECT D.LV1_PROD_LIST_EN_NAME AS LV1_RPOD_EN_NAME,
F.EXTERNAL_NAME AS EXTERNAL_NAME,
D.LV1_PROD_LIST_CODE AS LV1_PROD_LIST_CODE,
SUM(F.SO_QTY_ACT1) AS SO_QTY_ACT1,
SUM(F.SO_QTY_ACT2) AS SO_QTY_ACT2,
SUM(F.SO_QTY_ACT3) AS SO_QTY_ACT3,
SUM(F.SO_QTY_LAST) AS SO_QTY_LAST,
SUM(F.SO_QTY_WTD1) AS SO_QTY_WTD1,
SUM(F.SO_QTY_WTD2) AS SO_QTY_WTD2,
SUM(F.SO_QTY_WTD3) AS SO_QTY_WTD3,
SUM(F.SO_QTY_WTD_LAST) AS SO_QTY_WTD_LAST,
SUM(F.SO_QTY_MTD1) AS SO_QTY_MTD1,
SUM(F.SO_QTY_MTD2) AS SO_QTY_MTD2,
SUM(F.SO_QTY_MTD3) AS SO_QTY_MTD3,
SUM(F.SO_QTY_MTD_LAST) AS SO_QTY_MTD_LAST
FROM (
select EXTERNAL_NAME,
SUM(CASE WHEN F.PERIOD_ID=20230510 THEN F.SO_QTY ELSE NULL END) AS SO_QTY_ACT1,
SUM(CASE WHEN F.PERIOD_ID=20230509 THEN F.SO_QTY ELSE NULL END) AS SO_QTY_ACT2,
SUM(CASE WHEN F.PERIOD_ID=20230508 THEN F.SO_QTY ELSE NULL END) AS SO_QTY_ACT3,
SUM(CASE WHEN F.PERIOD_ID=20230510 THEN F.SO_QTY_LAST ELSE NULL END) AS SO_QTY_LAST,
SUM(CASE WHEN F.PERIOD_ID=20230510 THEN F.SO_QTY_WTD ELSE NULL END) AS SO_QTY_WTD1,
SUM(CASE WHEN F.PERIOD_ID=20230507 THEN F.SO_QTY_WTD ELSE NULL END) AS SO_QTY_WTD2,
SUM(CASE WHEN F.PERIOD_ID=20230430 THEN F.SO_QTY_WTD ELSE NULL END) AS SO_QTY_WTD3,
SUM(CASE WHEN F.PERIOD_ID=20230510 THEN F.SO_QTY_WTD_LAST ELSE NULL END) AS SO_QTY_WTD_LAST,
SUM(CASE WHEN F.PERIOD_ID=20230510 THEN F.SO_QTY_MTD ELSE NULL END) AS SO_QTY_MTD1,
SUM(CASE WHEN F.PERIOD_ID=20230430 THEN F.SO_QTY_MTD ELSE NULL END) AS SO_QTY_MTD2,
SUM(CASE WHEN F.PERIOD_ID=20230331 THEN F.SO_QTY_MTD ELSE NULL END) AS SO_QTY_MTD3,
SUM(CASE WHEN F.PERIOD_ID=20230510 THEN F.SO_QTY_MTD_LAST ELSE NULL END) AS SO_QTY_MTD_LAST
from BI_DASHBOARD.DM_MSS_OS_PC_AREA_SO_COL_D_F F
WHERE F.PERIOD_ID IN (20230510,20230509,20230508,20230507,20230430,20230430,20230331)
AND F.EXTERNAL_NAME IN ( SELECT MKT_NAME EXTERNAL_NAME
FROM BI_DASHBOARD.DM_MSS_ITEM_PRODUCT_D PRD
WHERE PRD.COMPANY_BRAND =any(array[string_to_array('HUAWEI,HONER',',')])
AND MKT_NAME<>'SNULL' GROUP BY MKT_NAME)
AND (F.LARGE_AREA_CODE IN ('') OR '' IS NULL OR ''= '')
AND (F.SMALL_AREA_CODE IN ('') OR '' IS NULL OR ''= '')
AND F.ORG_CODE=F.SIGN_COUNTRY_PROVINCE_CODE
AND F.ECOSYSTEM = 'AG'
AND F.SALES_FLAG = '1'
group by EXTERNAL_NAME)F
INNER JOIN BI_DASHBOARD.DM_MSS_ITEM_PRODUCT_D D ON F.EXTERNAL_NAME = D.MKT_NAME AND D.LV1_PROD_LIST_FLAG = 'MH'
WHERE 1=1
GROUP BY F.EXTERNAL_NAME,D.LV1_PROD_LIST_EN_NAME,D.LV1_PROD_LIST_CODE
在改写的SQL中,先对f表进行去重,然后再让其与d表进行关联,其执行计划如下图所示:
小结
关联前去重操作需要考虑使用场景,如果后续关联或者输出结果涉及到很多该表的字段,那么对该表做提前去重操作可能会起到相反的效果,影响语句执行性能,甚至影响结果集的准确性。因此,提前去重更适用于后续操作涉及到的字段不多,且提前去重不影响结果集的场景 (需要自己动手尝试一下)
5、总结
上述四个部分是梳理出来的较为常见的关联慢优化思路,像关联倾斜优化的解决办法是适用于大部分场景(只要识别出来存在关联时数据倾斜),调整关联顺序,不等值改等值关联、关联前去重这三种方法需要结合问题SQL具体考虑,不能直接使用。
- 点赞
- 收藏
- 关注作者
评论(0)