惰性求值
示例:惰性求值与急切求值
惰性求值的优势
- 查询优化:多个操作会编译成一条优化后的 SQL 查询
- 过滤器下推:在数据源层面应用过滤器
- 列裁剪:只读取所需列
- 延迟决策:可在运行时选择执行引擎
- 计划检查:可在执行前查看/调试查询
执行触发时机
自动触发
| 触发方式 | 示例 | 说明 |
|---|---|---|
print() / repr() | print(ds) | 显示结果 |
len() | len(ds) | 获取行数 |
.columns | ds.columns | 获取列名 |
.dtypes | ds.dtypes | 获取列数据类型 |
.shape | ds.shape | 获取形状 |
.index | ds.index | 获取行索引 |
.values | ds.values | 获取 NumPy 数组 |
| Iteration | for row in ds | 迭代行 |
to_df() | ds.to_df() | 转为 pandas |
to_pandas() | ds.to_pandas() | to_df 的别名 |
to_dict() | ds.to_dict() | 转为 dict |
to_numpy() | ds.to_numpy() | 转为数组 |
.equals() | ds.equals(other) | 比较 DataStore 对象 |
保持惰性执行的操作
| 操作 | 返回值 | 说明 |
|---|---|---|
filter() | DataStore | 添加 WHERE 子句 |
select() | DataStore | 添加列选择 |
sort() | DataStore | 添加 ORDER BY |
groupby() | LazyGroupBy | 准备 GROUP BY |
join() | DataStore | 添加 JOIN |
ds['col'] | ColumnExpr | 列引用 |
ds[['col1', 'col2']] | DataStore | 列选择 |
三阶段执行
阶段 1:SQL 查询构建 (惰性)
第 2 阶段:执行点
阶段 3:DataFrame 操作 (如有)
查看执行计划
explain() 查看实际会执行的内容:
Query
Response
verbose=True 查看更多详细信息:
缓存
缓存的工作原理
缓存失效
手动缓存控制
混合使用 SQL 和 Pandas 操作
与 SQL 兼容的操作
filter(),where()select()groupby(),agg()sort(),orderby()limit(),offset()join(),union()distinct()- 列运算 (数学运算、比较、字符串方法)
仅 Pandas 支持的操作
- 搭配自定义函数的
apply() - 带复杂聚合的
pivot_table() stack()、unstack()- 对已执行 DataFrame 的操作
混合型管道
执行引擎选择
自动模式 (默认)
强制使用 chDB 引擎
强制使用 pandas 引擎
性能影响
好:尽早过滤
不佳:过晚应用过滤器
推荐:尽早选择所需列
好:让 SQL 来完成工作
最佳实践总结
- 执行前先串联好各项操作 - 先构建完整查询,再统一触发一次
- 尽早过滤 - 在源头减少数据
- 只选择所需的列 - 列裁剪可提升性能
- 使用
explain()了解执行过程 - 运行前先调试 - 让 SQL 处理聚合 - ClickHouse 已针对此进行了优化
- 留意执行触发时机 - 避免意外过早执行
- 合理使用缓存 - 了解缓存何时会失效