PowerShellで数十万行以上のCSVを扱うと、
「読み込みが遅い」「メモリが一気に膨れる」「処理が固まったように見える」
といった問題が発生しがちです。
実はこれ、PowerShellのCSV処理の仕組みによる“あるある”で、
正しい書き方をすれば劇的に高速化できます。
この記事では、現場でも使われている 高速処理テクニック・実装例・注意点 をまとめます。
✔ なぜPowerShellはCSV処理が遅くなるのか
PowerShellの Import-Csv は便利ですが…
-
全行を一度にメモリへ展開する
-
オブジェクト化のコストが高い
-
数十万件を超えると数百MB〜GB級のメモリ使用
という特徴があります。
そのため、以下のような書き方は最も遅くなります。
✔ 高速化のポイントは「逐次読み込み」と「Stream処理」
PowerShellで数十万行を高速に処理する場合の最重要ポイントは以下。
💡 高速化の基本
-
Import-Csv を使わず StreamReader を使う
-
1行ずつ処理して不要になったデータは捨てる
-
Select-Object, Where-Object をループで使わない
-
型変換を最小限にする
-
出力は StringBuilder にまとめて最後に書き込む
✔ ベストプラクティス①:StreamReaderで逐次処理
最も高速でメモリ効率も良い方法です。
✔ 特徴
-
Import-Csv ではなく Split で直接取得 → 超高速
-
メモリ使用量は常に一定
-
数百万行でも余裕
✔ ベストプラクティス②:Import-Csv を使う場合の高速化
「やっぱりオブジェクトで扱いたい」という場合はこちら。
✔ 注意点
-
ForEach-Object -Parallelは PowerShell 7 以降限定 -
並列化は CPUコア数に依存
-
メモリ使用量は多め
✔ ベストプラクティス③:Select-Object / Where-Object を避ける
以下は遅くなりがち:
理由:すべての行をオブジェクトとして保持してしまう。
💡 改善
または、最速は StreamReader + Split。
✔ ベストプラクティス④:StringBuilderで出力バッファを作る
行ごとに Add-Content を実行すると激遅になります。
✔ StringBuilderを使う(高速)
✔ ベストプラクティス⑤:PowerShell 7 を使う
PowerShell 5.1 から PowerShell 7 に変えるだけで速度が倍以上になるケースが多いです。
理由
-
.NET Core ベースで高速化
-
ForEach-Object が最適化
-
Parallel 処理対応
✔ 実際の処理速度比較(目安)
| 手法 | 100万行の処理 | メモリ使用量 |
|---|---|---|
| Import-Csv → ループ | 数十秒〜数分 | 数百MB〜1GB超 |
| Import-Csv -Parallel | 10〜40秒 | 多め |
| StreamReader + Split | 5〜15秒 | 数MB |
※ PCスペックにより変動。
✔ まとめ:最速は「StreamReader+Splitによる逐次処理」
PowerShellで数十万行のCSVを高速処理するなら
✔ 最適解
-
逐次読み込み(ストリーム処理)
-
行ごとにSplitして必要な列だけ触る
-
StringBuilderでまとめて出力する
-
PowerShell 7 ならParallel化も可能
業務バッチで使う場合は、
StreamReader方式が最も安全で高速です。
実際の現場でも「メモリ溢れ対策」「速度改善」で最も採用されています。
