データ集計などで膨大なデータ(10万~100万件以上)のデータを処理するとき、デフォルト設定ではバッファを使うためメモリ使用量が大きくなってしまう。
メモリ不足で処理が落ちないように非バッファクエリを使いたい。
Eloquent ORMでの使い方がマニュアルに載っていないので調べた。
非バッファクリエについてはこちら。
PHPマニュアル - バッファクエリと非バッファクエリ
config/database.phpで設定
connections
の該当接続名の設定の中にoptions
を追加する。
'connections' => [
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'database'),
'username' => env('DB_USERNAME', 'user'),
'password' => env('DB_PASSWORD', 'password'),
'options' => [
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false,
],
],
]
バッチ処理とか特定の場所だけで設定
$config_key = 'database.connections.mysql.options';
$options = [
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false,
];
\Config::set($config_key, $options);
※これをDB接続が始まる前に実行すること。
Empty row packet body
数百万件とか大量のデータを処理しようとすると「Empty row packet body」というエラーが出てしまう時がある。
MySQLの設定で以下のパラメータを長めにすることで緩和。
100%防ぐことが出来ないのでchunkを使った方がよいかもしれない。
net_read_timeout
net_write_timeout
おまけ:その他オプション
持続的接続は$options
にPDO::ATTR_PERSISTENT
を追加
$options = [
PDO::ATTR_PERSISTENT => true,
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false,
];