Laravel mongodbデータエクスポートcsv方式テスト
39129 ワード
データ量:10 w
需要:オーダー表関連ロット表エクスポートライン管理データ
jenssegers/mongodbを応用してパケットアクセスデータを拡張することは便利ですが、パフォーマンスの問題をもたらすのではないでしょうか.
ツール/環境:homestead+jenssegers/mongodb":"^3.2+console
使用時間73 s
ツール/環境:homestead+console
なんと172 sも使っていたのに、もっと多くなった!!
[‘allowDiskUse’=>true]という設定のせいだと推測されますが、trueに設定しないとメモリが足りませんね.
s o r t用sort用sort用skipでページングしないでください.
そして...
書き出しは37000条の時点で172 sを超え、そしてどんどんゆっくりと...翌日発見:2213 s!!!what?!!!
簡単にSkipを使ってクエリーをしないでください.そうしないと、データ量が大きくなると性能が急激に低下します.これはSkipが1本1本数えているので、多くなると自然に遅くなります.
mongodb集約ドキュメントの探索中...
需要:オーダー表関連ロット表エクスポートライン管理データ
jenssegers/mongodbを応用してパケットアクセスデータを拡張することは便利ですが、パフォーマンスの問題をもたらすのではないでしょうか.
jenssegers/mongodb拡張エクスポートの適用
ツール/環境:homestead+jenssegers/mongodb":"^3.2+console
$t = microtime(true);
$order_id = '';
$is_true = true;
$limit = 1000;
$file_name = storage_path('files/csv_test.csv');
$fp = fopen($file_name, 'w');
while ($is_true) {
$query = \App\Models\Order_test::query()
->with('batch')
->where('payment.status', '>', \App\Models\Order::PAYMENT_UNPAID);
if (!empty($order_id)) {
$query->where('id','>', $order_id);
}
$orders = $query->orderBy('id', 'asc')->limit($limit)->get();
$order_count = count($orders);
if ($order_count > 0) {
//
if (empty($order_id)) {
fwrite($fp, chr(0xEF) . chr(0xBB) . chr(0xBF));
$title_list = [
' ',
' ',
' ',
' ',
' ',
' ',
' 1',
' 2',
' '
];
fputcsv($fp, $title_list);
}
//
foreach ($orders as $order) {
$order_id = $order['id'];
$data = [
'order_id' => $order_id.'\t',
'pay_time' => $order->pay_time ?? '',
'order_status' => \App\Models\Order::$_statusArr[$order->status] ?? '',
'products_cost' => $order->products_cost,
'cost_total' => $order->total,
'items_total' => $order->items_total,
'batch_field1' => $order->batch['field1']??'';,
'batch_field2' => $order->batch['field2']??'';,
'created_at' => (string)$order->created_at,
];
fputcsv($fp, $data);
}
}
//
if ($order_count < $limit) {
$is_true = false;
//
fclose($fp);
}
}
$tl = microtime(true)-$t;
dd($tl);
使用時間73 s
オリジナルエクスポート
ツール/環境:homestead+console
Artisan::command('tiway:mongo_raw', function () {
$t = microtime(true);
// mongo
$con = new \MongoDB\Client("mongodb://username:password@host:port/");
$db = $con->selectDatabase('test');
$collection = $db->selectCollection('order_test');
$order_id = '';
$is_true = true;
//
$limit_item = 1000;
$file_name = storage_path('files/mongo_raw.csv');
$fp = fopen($file_name, 'w');
while ($is_true) {
//
if (empty($order_id)) {
fwrite($fp, chr(0xEF) . chr(0xBB) . chr(0xBF));
$title_list = [
' ',
' ',
' ',
' ',
' ',
' ',
' 1',
' 2',
' '
];
fputcsv($fp, $title_list);
}
$pipeline = [];
$match = ["payment.status" => ['$gt'=> \App\Models\Order::PAYMENT_UNPAID]];
if (!empty($order_id)) {
$order_id_match = ["id" => ['$gt'=> $order_id]];
$match += $order_id_match;
}
array_push($pipeline,['$match' => $match]);
$sort = [
'$sort' =>['id'=>1],
];
$limit = [
'$limit'=>$limit_item
];
array_push($pipeline,$limit,$sort);
// batch
$batch_pipe = [
'$lookup' => [
"from" => "easyeda_batch",
// order
"localField" => "batch_num",
// user
"foreignField" => "batch_num",
// order
"as" => "batch",
],
];
array_push($pipeline,$batch_pipe);
//
$allow_disk = ['allowDiskUse'=> true];
$orders = $collection->aggregate($pipeline,$allow_disk);
$row = 0;
//
foreach ($orders as $order) {
$order_id = $order->id;
$data = [
'order_id' => $order_id.'\t',
'pay_time' => $order->pay_time ?? '',
'order_status' => \App\Models\Order::$_statusArr[$order->status] ?? '',
'products_cost' => $order->products_cost,
'cost_total' => $order->total,
'items_total' => $order->items_total,
'batch_field1' => $order->batch['field1']??'';,
'batch_field2' => $order->batch['field2']??'';,
'created_at' => (string)$order->created_at,
];
$row ++;
fputcsv($fp, $data);
}
//
if ($row < $limit_item) {
$is_true = false;
//
fclose($fp);
}
}
$tl = microtime(true)-$t;
dd($tl);
});
なんと172 sも使っていたのに、もっと多くなった!!
[‘allowDiskUse’=>true]という設定のせいだと推測されますが、trueに設定しないとメモリが足りませんね.
In Aggregate.php line 219:
Sort exceeded memory limit of 104857600 bytes, but did not opt in to external
sorting. Aborting operation. Pass allowDiskUse:true to opt in.
s o r t用sort用sort用skipでページングしないでください.
そして...
書き出しは37000条の時点で172 sを超え、そしてどんどんゆっくりと...翌日発見:2213 s!!!what?!!!
簡単にSkipを使ってクエリーをしないでください.そうしないと、データ量が大きくなると性能が急激に低下します.これはSkipが1本1本数えているので、多くなると自然に遅くなります.
mongodb集約ドキュメントの探索中...