一、分区失效
1. 子查询
用子查询限定分区时, in操作会转成join操作, 扫描表数据时无法利用分区过滤, 要等到join操作时才过滤出所需分区的数据, 因此分区限制时最好使用常量;
-- 子查询限制分区, 可能导致分区过滤失效
select
*
from
tbl_a
where
dt = '20231005'
and app_name in ( select distinct app_name from fm_event_cfg )
;
-- 外部传参或常量限制分区, 不会导致分区失效
select
*
from
tbl_a
where
dt = '20231005'
and instr('${app_names}', app_name) > 0 -- 分区字段类型无限制
-- and app_name in ('${app_names}') -- 分区字段是数值类型
;
2. or条件
or条件覆盖了分区条件, or条件两端注意加();
-- (dt是时间分区, name是表字段)
-- 这种or写法会导致dt分区失效扫全表
select
id
,name
from
tbl_name
where
dt = 20231027
and name = 'shy' or name = 'ssjt'
;
-- 避免分区失效扫全表, or条件注意加()
select
id
,name
from
tbl_name
where
dt = 20231027
and ( name = 'shy' or name = 'ssjt' )
;
-- (dt是一级分区, type是二级分区), 下面查询二级分区过滤失效, 会扫描type=22分区之外的所有数据
select
*
from
tbl_name
where
dt = '20231106'
and (
(
type in ('11') and event = 'aa'
)
or
(
type not in ('22') and event = 'bb'
)
)
;
二、过滤函数
1. 高效过滤算子
在Spark中,instr和in都是用于字符串匹配的函数,但它们的实现方式不同,因此效率也可能会有所不同。
instr函数用于返回一个字符串在另一个字符串中第一次出现的位置,如果未找到则返回0。它的实现方式是通过遍历字符串,逐个字符进行比较,直到找到匹配的子串或遍历完整个字符串。
in函数用于检查一个字符串是否包含另一个字符串,返回布尔值。它的实现方式是通过使用KMP算法或BM算法等高效的字符串匹配算法,在不需要遍历整个字符串的情况下快速找到匹配的子串。
因此,从算法的角度来看,in函数在查找字符串匹配时可能更高效,尤其是当目标字符串较长时。
三、 数据异常
1. 某天的数据异常,排查时要看该天前后一段时间内的趋势