Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
12
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

Laravel Eloquent ORMでMySQLの非バッファクエリを使う

データ集計などで膨大なデータ(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

おまけ:その他オプション

持続的接続は$optionsPDO::ATTR_PERSISTENTを追加

$options = [
    PDO::ATTR_PERSISTENT => true,
    PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false,
];
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
12
Help us understand the problem. What are the problem?