DBT staging层使用SELECT *是否合理?成本性能层面的疑问
关于DBT Staging层使用SELECT *的疑问解答
你的逻辑完全站得住脚——从源表直接用SELECT *确实存在你提到的这些隐患:会拉取不必要的数据增加存储和查询成本、拖慢查询速度,而且无法直观看到依赖的列,缺乏透明度。
官方文档和教程里使用这种写法,主要是出于以下几个实际考量:
- 简化演示,聚焦核心语法:示例的目的是教你dbt的基础用法(比如
{{ source() }}引用、CTE结构、字段映射),用SELECT *能避免把源表所有列都列出来,让代码更简洁,不会让学习者被无关的字段分散注意力。 - 适配源表结构的动态变化:如果上游源表经常新增列,用
SELECT *可以让staging层自动同步这些新列,不用每次都手动修改代码。当然这是一把双刃剑,灵活性的代价就是可能引入不需要的列。 - 现代数据仓库的优化器兜底:像BigQuery、Snowflake这类主流数据仓库的查询优化器会自动做列裁剪和谓词下推——也就是说,虽然你在source CTE里写了
SELECT *,但后续transformed层只用到了id和orderid,优化器会直接从源表只读取这两列,不会真的拉取所有列,实际的性能和成本损耗远没有理论上那么严重。
生产环境的建议
如果你的场景对成本、性能或数据透明度要求较高,更推荐:
- 显式列出需要的列,比如把source CTE改成:
这样能明确依赖的字段,避免意外引入冗余数据。source as ( select id, orderid from {{ source('stripe','payment') }} ) - 如果需要兼顾源表结构的灵活性,可以用dbt内置的
{{ get_columns_in_source() }}宏动态获取列,再排除不需要的字段,平衡灵活性和可控性。
内容的提问来源于stack exchange,提问作者MattSt
相关产品推荐
相关产品推荐

