クエリプラン
Polarsでは、Lazy クエリには以下の2つがあります:
- 提供したコードの手順セットのままの非最適化プラン
- クエリオプティマイザーによる変更を加えた最適化プラン
非最適化プランと最適化プランの両方を、視覚化や文字列出力で理解することができます。
以下のクエリを考えてみましょう:
q1 = (
    pl.scan_csv("docs/data/reddit.csv")
    .with_columns(pl.col("name").str.to_uppercase())
    .filter(pl.col("comment_karma") > 0)
)
非最適化クエリプラン
Graphviz による視覚化
クエリプランの視覚化には、Graphvizをインストールし、PATHに追加する必要があります。
まず、optimized=Falseを設定して非最適化プランを視覚化します。
q1.show_graph(optimized=False)
クエリプランの視覚化は、下から上に向けて読みます。視覚化では:
- 各ボックスがクエリプランの段階を表しています
- sigmaは- SELECTIONを表し、フィルター条件を示しています
- piは- PROJECTIONを表し、列のサブセットを選択していることを示しています
クエリプランの出力
explain(optimized=False)で非最適化プランを出力することもできます。
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で最適化プランを視覚化します。
q1.show_graph()
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の読み込み時にフィルターを適用できることを見つけました。これは_Predicate Pushdown_と呼ばれる最適化です。