跳到内容

查询计划

对于任何惰性查询,Polars 都有两种计划:

  • 一个未优化计划,包含我们提供的代码步骤集合,以及
  • 一个优化计划,包含由查询优化器所做的更改

我们可以通过可视化和文本打印的方式来理解未优化和优化的查询计划。

下面我们考虑以下查询

q1 = (
    pl.scan_csv("docs/assets/data/reddit.csv")
    .with_columns(pl.col("name").str.to_uppercase())
    .filter(pl.col("comment_karma") > 0)
)

未优化查询计划

Graphviz 可视化

要创建查询计划的可视化,应安装 Graphviz 并将其添加到您的 PATH 环境变量中。

首先,我们通过设置 optimized=False 来可视化未优化计划。

show_graph

q1.show_graph(optimized=False)

查询计划可视化应从下往上阅读。在可视化中

  • 每个框对应查询计划中的一个阶段
  • sigma 代表 SELECTION,表示任何过滤条件
  • pi 代表 PROJECTION,表示选择列的子集

打印的查询计划

我们还可以使用 explain(optimized=False) 打印未优化计划

explain

q1.explain(optimized=False)

FILTER [(col("comment_karma")) > (0)] FROM WITH_COLUMNS:
 [col("name").str.uppercase()]

    CSV SCAN data/reddit.csv
    PROJECT */6 COLUMNS

打印的计划也应从下往上阅读。此未优化计划大致相当于:

  • data/reddit.csv 文件读取
  • 读取所有 6 列(其中 PROJECT */6 COLUMNS 中的 * 通配符表示选取所有列)
  • name 列转换为大写
  • comment_karma 列应用筛选器

优化查询计划

现在我们使用 show_graph 可视化优化计划。

show_graph

q1.show_graph()

我们还可以使用 explain 打印优化计划

explain

q1.explain()

 WITH_COLUMNS:
 [col("name").str.uppercase()]

    CSV SCAN data/reddit.csv
    PROJECT */6 COLUMNS
    SELECTION: [(col("comment_karma")) > (0)]

优化计划是:

  • 从 Reddit CSV 读取数据
  • 当 CSV 逐行读取时,对 comment_karma 列应用筛选器
  • name 列转换为大写

在这种情况下,查询优化器已识别出可以在从磁盘读取 CSV 时应用 filter,而不是将整个文件读入内存后再应用筛选器。此优化称为 *谓词下推* (Predicate Pushdown)。