次のような基本的なコードセットがあります (コントローラー内):
$sql = 'select * from someLargeTable limit 1000';
$em = $this->getDoctrine()->getManager();
$conn = $em->getConnection();
$statement = $conn->prepare($sql);
$statement->execute();
私の難点は、結果セットが数レコードしかない場合、メモリ使用量がそれほど悪くないことです。$statement->execute(); を実行する前後にデバッグ情報をエコーしました。コードの一部であり、私の実装では次のことがわかりました。
pre-execute... rowCount :: 0 memory: 49.614 MB
post-execute... rowCount :: 1000 memory: 50.917 MB
これを 1000 レコードから 10k に移動すると、MB 使用量の差は 13 MB に拡大します
pre-execute... rowCount :: 0 memory: 49.614 MB
post-execute... rowCount :: 10000 memory: 62.521 MB
最終的に、約 50k レコードを取得すると、最大メモリ割り当てに近づきます。
pre-execute... rowCount :: 0 memory: 49.614 MB
post-execute... rowCount :: 50000 memory: 114.096 MB
この実装では、データの CSV を取得できるようにするコントローラー (さらに言えばコマンド) を作成する方法はありません。確かに、50,000 件以上のエントリは多くのように聞こえますが、その理由は疑問ですが、それは問題ではありません。
私の最終的な質問は、DBAL/接続またはDBAL/ステートメントに、実行時にPHPではなくSQL内にデータ全体をバッファリングするように指示することは可能ですか? たとえば、1,000 万行ある場合、最初の 10,000 行のみを PHP に送信するには、@statement->fetch();を使用してそれらを調べます。カーソルが 10k の終わりに到達したら、配列を切り捨てて、DB から次の 10k をフェッチしますか?