【调优实践】不等值关联优化(OR算子)

举报
门前一棵葡萄树 发表于 2023/09/06 17:35:11 2023/09/06
【摘要】 使用场景:本案例适合满足以下条件的场景关联条件使用OR连接关联条件中使用同一列做数据筛选1. 原始语句SELECT t2.PARTNER_CHANNEL_CODE AS CHANNEL_ID ,t1.COUNTRY_CODE ,t1.BRAND ,t2.CHANNEL_ID AS CHANNEL_ID2FROM t1LEFT JOIN t2ON ( t2.CHANN...

使用场景:本案例适合满足以下条件的场景

  1. 关联条件使用OR连接
  2. 关联条件中使用同一列做数据筛选

1. 原始语句

SELECT
	t2.PARTNER_CHANNEL_CODE   AS CHANNEL_ID
	,t1.COUNTRY_CODE
	,t1.BRAND
	,t2.CHANNEL_ID            AS CHANNEL_ID2
FROM
	t1
LEFT JOIN
	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

2. 性能分析

通过查询计划分析发现,t1表和t2表关联走了NEST LOOP,查询整体耗时45S,NEST LOOP耗时占用整个查询执行耗时的96%。因此考虑能否通过SQL改写或HINT规避NEST LOOP。观察发现t1表和t2表包含两个关联关联条件,两个关联条件之间使用OR连接,属于非等值关联,因此不能走HASH JOIN。进一步分析SQL发现两个关联条件中都使用t1.TYPE进行过滤筛选:

(t2.CHANNEL_ID           =  t1.CHANNEL_ID  AND  t1.TYPE='DR')
OR  (t2.PARTNER_CHANNEL_CODE =  t1.CHANNEL_ID  AND  t1.TYPE='ALL' )

该关联条件包含以下三种关联组合:

  1. t1表中t1.TYPE='DR'的行,只能使用第一个关联条件与t2表关联;
  2. t1表中t1.TYPE='ALL'的行,只能使用第二个关联条件与t2表关联;
  3. t1表中t1.TYPE NOT IN ('ALL','DR')的行,不与t2表关联,直接补空。

t1表中的一行数据只能选择这三个关联条件中的一个与t2表关联,因此该关联条件可以改写为不同关联条件的UNION ALL(UNION会去重,不等价)。

3. 优化改写

改写后SQL如下所示:

SELECT
	CHANNEL_ID
	,COUNTRY_CODE
	,BRAND
	,CHANNEL_ID
FROM 
(
SELECT
	t2.PARTNER_CHANNEL_CODE   AS CHANNEL_ID
	,t1.COUNTRY_CODE
	,t1.BRAND
	,t2.CHANNEL_ID            AS CHANNEL_ID2
FROM
	t1
LEFT JOIN
	t2
ON
	t2.CHANNEL_ID = t1.CHANNEL_ID
WHERE
	t1.TYPE = 'DR'

UNION ALL
SELECT
	t2.PARTNER_CHANNEL_CODE   AS CHANNEL_ID
	,t1.COUNTRY_CODE
	,t1.BRAND
	,t2.CHANNEL_ID            AS CHANNEL_ID2
FROM
	t1
t2
ON  t2.PARTNER_CHANNEL_CODE =  t1.CHANNEL_ID
WHERE t1.TYPE='ALL'
UNION ALL
SELECT
t2.PARTNER_CHANNEL_CODE   AS CHANNEL_ID
,t1.COUNTRY_CODE
,t1.BRAND
,t2.CHANNEL_ID            AS CHANNEL_ID2
FROM  t1
LEFT JOIN
t2
ON  FALSE
WHERE t1.TYPE NOT IN ('ALL','DR')
)
GROUP BY CHANNEL_ID,COUNTRY_CODE,BRAND,CHANNEL_ID

改写后SQL变为三个子查询的UNION ALL,执行时间缩减至1s以内,性能优化45倍。

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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