Rumah > Soal Jawab > teks badan
Saya mempunyai model yang dipanggil "Produk" Saya mempunyai model bernama Note_voucher_line
Ini adalah hubungan dalam produk
public function get_note_voucher_lines() { return $this->hasMany('App\Models\Note_voucher_line','product_id','id')->orderBy('date','asc')->orderBy('note_voucher_id','asc'); }
Sekarang kadang-kadang saya perlu menggelungkan produk dengan kod seperti ini
$products = Product::whereBetween('id',[$num1,$num2])->get(); foreach($products as $product) { $lines = $product['get_note_voucher_lines']; // when i use this relation it tack long long time }
Model Note_voucher_line
mempunyai lebih 300k baris
Saya mempunyai indeks pada migration
Ini ialah note_voucher_lines
penghijrahan indeks dalaman
Schema::table('note_voucher_lines', function($table) { $table->foreign('note_voucher_id')->references('id')->on('note_vouchers'); $table->foreign('user_id')->references('id')->on('users'); $table->foreign('journal_entry_id')->references('id')->on('journal_entries'); $table->foreign('warehouse_id')->references('id')->on('warehouses'); $table->foreign('product_id')->references('id')->on('products'); $table->foreign('cost_center_id')->references('id')->on('cost_centers'); $table->foreign('unit_id')->references('id')->on('units'); $table->foreign('is_it_bonus')->references('id')->on('status'); $table->foreign('note_voucher_type_id')->references('id')->on('note_voucher_types'); $table->foreign('posting_state_id')->references('id')->on('posting_status'); $table->foreign('product_total_quantity_id')->references('id')->on('product_total_quantitys'); $table->foreign('is_componentable')->references('id')->on('status'); $table->foreign('approved_state_id')->references('id')->on('approval_status'); $table->foreign('currency_id')->references('id')->on('currencies'); $table->foreign('branch_id')->references('id')->on('branches'); $table->foreign('created_by')->references('id')->on('users'); $table->foreign('deleted_by')->references('id')->on('users'); });
Jadual produk mempunyai indeks yang dipanggil product_id Sebarang bantuan di sini untuk menjadikannya lebih pantas Terima kasih
P粉4929595992024-03-31 12:05:45
Dalam kes ini, memuatkan hubungan anda dengan penuh semangat boleh membantu.
$products = Product::whereBetween('id',[$num1,$num2])->with('get_note_voucher_lines')->get(); foreach($products as $product) { $lines = $product->get_note_voucher_lines; // This should be faster and note that this is the right way to fetch laravel relation not as an array }
Apa yang berlaku di sini ialah kami menggunakan jadual with()
方法在每次迭代中从 note_voucher_lines
untuk pramuat 2k baris (dengan mengandaikan jadual produk anda mengandungi 2k baris) dan bukannya satu baris yang dimuatkan sebelum ini. Ini mengurangkan bilangan panggilan rangkaian yang dibuat ke pelayan pangkalan data, kini bukannya 300k panggilan, ia membuat 300k/2k panggilan.
Nota: Anda juga harus mempertimbangkan untuk menggunakan pemuatan blok untuk produk anda untuk mengelak daripada mencapai had memori apabila data anda terus berkembang. https://laravel.com/docs/10.x/eloquent#chunking-results
P粉2447306252024-03-31 09:24:23
Sebab utama kelewatan nampaknya adalah malas memuatkan hubungan get_note_voucher_lines.
Setiap kali anda mengakses perhubungan ini dalam gelung, Laravel akan membuat pertanyaan berasingan untuk mendapatkan baris yang berkaitan. Inilah yang dipanggil masalah N+1.
Untuk mengurangkan perkara ini, gunakan pemuatan bersemangat:
$products = Product::whereBetween('id',[$num1,$num2])->with('get_note_voucher_lines')->get();
Anda juga boleh menggunakan chunking untuk memproses data besar:
Product::whereBetween('id',[$num1,$num2])->with('get_note_voucher_lines')->chunk(100, function ($products) { foreach ($products as $product) { $lines = $product->get_note_voucher_lines; }});
Pastikan terdapat indeks pada medan id. Anda menyebut mempunyai indeks, tetapi pastikan ia adalah indeks yang betul dan bukan hanya kekangan kunci asing.