示例说明
eager 模式下每个操作立即物化中间结果,链式转换会把整表反复重算。lazy 模式把整条查询编译成逻辑计划再优化:过滤条件推到扫描最近处执行,未使用的列在投影阶段裁掉,流式执行让内存峰值与表大小解耦——数据量从 GB 级起步时这些优化是质变的。
技术要点
- 谓词下推把过滤推近数据源
- 投影裁剪移除未引用列
- streaming 让聚合内存恒定
代码解读
首个查询过滤浏览事件后按天分组,聚合表达式同时给出去重用户数、金额合计与众数事件,collect 的 streaming 开关启用流式执行。第二个查询演示查看优化后的逻辑计划——优化器已经把选择列收缩到两列并下推条件。
使用建议
collect 之前全部是声明,别在中间插入 eager 操作打断优化。复杂 join 也能受益于计划重排。大规模生产场景配合扫描文件源直接全链路流式。
代码示例
import polars as pl
events = pl.DataFrame({
'user_id': [1, 2, 3, 4, 5, 6],
'event': ['view', 'click', 'view', 'purchase', 'click', 'view'],
'amount': [0, 0, 0, 120, 0, 0],
'day': ['2026-10-21', '2026-10-21', '2026-10-22', '2026-10-22', '2026-10-22', '2026-10-22'],
})
lazy = events.lazy()
report = (
lazy
.filter(pl.col('event') != 'view')
.group_by('day')
.agg(
active_users=pl.col('user_id').n_unique(),
revenue=pl.col('amount').sum(),
top_event=pl.col('event').mode().first(),
)
.sort('day')
.collect(streaming=True)
)
print(report)
plan = (
lazy.filter(pl.col('amount') > 0)
.select(['day', 'amount'])
.collect_optimized_plan()
)
print('optimized logical plan nodes:', len(str(plan).splitlines()))