如何在Teradata Vantage中高效实现分区表的UNPIVOT操作
Teradata Vantage 16.20 UNPIVOT视图分区过滤下推解决方案
问题核心原因
TD_UNPIVOT属于Teradata系统内置的表函数(UDTF),默认情况下优化器不会自动推导UDTF的透传列,因此外部的过滤条件无法穿透UDTF下推到源表,导致全表扫描。标准UNPIVOT语法在Teradata内部也是转成UDTF实现,所以也存在同样的问题。
解决方案
方案1:用CROSS JOIN + 固定序列替代UNPIVOT(最稳定)
这种方式使用标准SQL的关系运算实现转置,优化器可以正常识别谓词下推规则,分区裁剪稳定生效:
CREATE VIEW unpivoted_my_table AS SELECT t.event_id, t.event_date, t.event_timestamp, LPAD(s.seq, 3, '0') AS seqnum, CASE s.seq WHEN 1 THEN t.value_001 WHEN 2 THEN t.value_002 WHEN 3 THEN t.value_003 WHEN 4 THEN t.value_004 WHEN 5 THEN t.value_005 WHEN 6 THEN t.value_006 WHEN 7 THEN t.value_007 WHEN 8 THEN t.value_008 WHEN 9 THEN t.value_009 WHEN 10 THEN t.value_010 WHEN 11 THEN t.value_011 WHEN 12 THEN t.value_012 WHEN 13 THEN t.value_013 WHEN 14 THEN t.value_014 WHEN 15 THEN t.value_015 WHEN 16 THEN t.value_016 WHEN 17 THEN t.value_017 WHEN 18 THEN t.value_018 WHEN 19 THEN t.value_019 WHEN 20 THEN t.value_020 END AS val FROM my_table t CROSS JOIN ( SELECT 1 AS seq UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12 UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL SELECT 15 UNION ALL SELECT 16 UNION ALL SELECT 17 UNION ALL SELECT 18 UNION ALL SELECT 19 UNION ALL SELECT 20 ) s;
使用的时候直接查询视图加过滤即可:
SELECT * FROM unpivoted_my_table WHERE event_date BETWEEN DATE '2021-01-01' AND DATE '2021-01-02';
该方案和源表硬编码过滤的性能完全一致,分区裁剪正常生效。
方案2:显式指定TD_UNPIVOT的KEEP_COLUMNS参数
如果需要继续使用TD_UNPIVOT语法,可以通过显式声明透传列,让优化器识别到过滤字段不需要参与转置,可以直接下推:
CREATE VIEW unpivoted_my_table AS SELECT event_id, event_date, event_timestamp, seqnum, val FROM TD_UNPIVOT( ON my_table USING VALUE_COLUMNS('val') UNPIVOT_COLUMN('seqnum') COLUMN_LIST('value_001','value_002','value_003','value_004','value_005','value_006','value_007','value_008','value_009','value_010','value_011','value_012','value_013','value_014','value_015','value_016','value_017','value_018','value_019','value_020') COLUMN_ALIAS_LIST('001','002','003','004','005','006','007','008','009','010','011','012','013','014','015','016','017','018','019','020') KEEP_COLUMNS('event_id','event_date','event_timestamp') ) t;
显式指定KEEP_COLUMNS后,优化器会将event_date的过滤条件直接下推到源表扫描阶段,触发分区裁剪。
额外优化建议
- 优先选择方案1,兼容性更强,优化器规则更成熟,不会受UDTF相关参数影响
- 如果使用方案2,可以会话级开启UDTF谓词下推开关保证效果:
SET SESSION UDTF_PREDICATE_PUSHDOWN = ON;
内容的提问来源于stack exchange,提问作者LukeL
相关产品推荐
相关产品推荐

