J'ai un modèle appelé "Produit" J'ai un modèle appelé Note_voucher_line
C'est la relation au sein du produit
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'); }
Maintenant, je dois parfois boucler le produit avec un code comme celui-ci
$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
a plus de 300 000 lignes
J'ai un index sur migration
Il s'agit de la note_voucher_lines
migration d'index interne
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'); });
La table product a un index appelé product_id Toute aide ici pour le rendre plus rapide Merci
Dans ce cas, charger votre relation avec impatience peut être utile.
Ce qui se passe ici, c'est que nous utilisons la table
with()
方法在每次迭代中从note_voucher_lines
pour précharger 2 000 lignes (en supposant que votre table de produits contient 2 000 lignes) au lieu de la ligne chargée auparavant. Cela réduit le nombre d'appels réseau effectués vers le serveur de base de données. Désormais, au lieu de 300 000 appels, il effectue 300 000/2 000 appels.Remarque : vous devez également envisager d'utiliser le chargement par blocs pour votre produit afin d'éviter d'atteindre les limites de mémoire à mesure que vos données continuent de croître. https://laravel.com/docs/10.x/eloquent#chunking-results
La principale raison du retard semble être le chargement paresseux de la relation get_note_voucher_lines.
Chaque fois que vous accédez à cette relation dans une boucle, Laravel effectuera une requête distincte pour obtenir les lignes pertinentes. C’est ce qu’on appelle le problème N+1.
Pour atténuer cela, utilisez le chargement rapide :
Vous pouvez également utiliser le chunking pour traiter le Big Data :
Assurez-vous qu'il y a un index sur le champ id. Vous avez mentionné avoir un index, mais assurez-vous qu'il s'agit d'un index approprié et pas seulement d'une contrainte de clé étrangère.