14
12

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-03-06

データ集計などで膨大なデータ(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,
];
14
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
12