何回か発言していたのだけど念押しで言っておきますね。Power Query は Excel ではないですからね。ワークシート上での操作のノリで "適用するステップ" をキメたら駄目ね。間違った処理がされることがあっても、パフォーマンスが悪くなってもよいのだというのなら、ご自由にどうぞ。
ポチポチ操作で出力される条件が異なることがある
以前ポストしたので詳しくはこっちで。
ポチポチ操作で候補を選択するとき、選択した候補の割合で Table.SelectRows 関数の condition が異なるのだ。表示しきれない候補が存在することもあるし、のちのちデータが追加されることがあるのだから操作が簡単な分得られる結果について注意深く観察することが大事。
最適ではない Table.SelectRows 関数を使ってしまう
Table.SelectRows 関数の目的としてはテーブルの行を絞り込むことにある。しかし、その理解では不十分だ。
Table.SelectRows(table as table, condition as function) as table
table すべての行で condition を評価するということだ。すべての行というのが当たり前で重要なのだけど、すべての行を評価する必要がない、もしくは、すべての行を評価するべきではないパターンの行の絞り込みもあるよね。
例えば、
Column1 |
---|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
... |
というテーブルがあったとき、先頭の2行に絞り込みたいのに、 |
Table.SelectRows( table, each [Column1] <= 2 )
という処理を華麗にキメちゃう人が多いんだよね。よく考えてね。 "先頭の" という必要な条件はどこにやったんだい?違うよね。処理される予定のテーブルは、わずか10万行かもしれないし100億行かもしれないよね。 100億回の評価をしたいの?
Table.FirstN( table, 2 )
ソースが 1GB の CSV ファイルとしたとき、選択した手段に間違いがなければ 4KB ほどの読み込みで済むところ、1GBまるまる読み込むっていうことになるわけ。
行の並び替えと組み合わせ
対象の列で最小の値になる1行に絞り込むなら、
Table.MinN( table, { "Column1", Order.Accending }, 1 )
Table.MinN、Table.MaxN は内部的に Table.Sort が含まれているので、
Table.FirstN(
Table.Sort( table, { "Column1", Order.Ascending } ),
1
)
クエリフォールディングが利用できる記述になる可能性が高いので、この記述が望ましいわけ。不用意に Table.Buffer 関数使ったり、Table.AddIndexColumn 関数で Index列を追加してアレコレするというのはやらないほうがよいのである。
Table.SelectRows 関数 以外で テーブルの行を絞り込む関数
Table.SelectRows 関数 以外で テーブルの行を絞り込む関数があるわけで、
それぞれを使用し得られた結果がたまたま同じということはある。でも、Mashup engine の動作が異なるので、どのような動作をしているのかよーく勉強するとよい。クエリフォールディングが利用できる記述/できない記述も踏まえてね。
思ったこと🙄
テーブルの行を絞り込みたいなというとき、Table.Skip、Table.FirstN で要件を満たすなら優先して検討することでトラブルは激減する。また、Table.Sort 関数の挙動がよくわからんというなら、Table.MaxN、Table.MinN を使うとよい。
Power Query の処理はどんだけ拗らせても速くはならないのだ。じゃぁどう向き合うかは簡単。処理が遅くならない、もしくは遅くなりにくい選択をすべきなんじゃね?
その他