برنامه نویسی

نحوه جلوگیری از نمایش داده های N + 1 در PHP

من چند روز پیش در حال بررسی یک پایگاه کد Laravel بودم و یک اشتباه پرس و جو مشترک N+1 را دیدم. پرس و جو n+1 برنامه های ما را به طور ناآگاهانه کند می کند. از آنجا که چیزهایی که قرار است یکباره اجرا شوند 4 تا 5 بار اجرا می شوند.

من تأکید خواهم کرد دو نمونه های پرس و جو N+1 و راه حل (های) آنها.

سناریو یکی:
ما در حال تلاش برای ایجاد یک آرایه برای ایجاد معاملات در پایگاه داده هستیم.

اشتباه


foreach ($request->transactions as $transaction) {
   Transaction::create([
     "transactionId" => $transaction->id,
     "amount" => $transaction->amount
     // and the rest of the code
   ]);
}

این یک مورد کلاسیک از پرس و جو N+1 است زیرا شما برای هر بار که از طریق یک حلقه می روید ، یک رکورد جدید ایجاد می کنید ، و این باعث می شود برنامه شما یا هر مسیری که این عملکرد را فراخوانی می کند ، کند شود.

راه حل ساده برای این کار خواهد بود.

  1. قبل از خط حلقه Foreach یک آرایه خالی اعلام کنید.
  2. از طریق آرایه حلقه کنید و آماده شوید تا رکورد را در پایگاه داده وارد کنید.
  3. همه آن را به یکباره در پایگاه داده وارد کنید.

اجرای توضیحات.

قبل از خط حلقه Foreach یک آرایه خالی را اعلام کنید

$storeTransaction = [];

از طریق کد حلقه کنید و نحوه وارد کردن آن را آماده کنید

$now = now();

foreach ($request->transactions as $transaction) {
  $storeTransaction[] = [
     "transactionId" => $transaction->id,
     "amount" => $transaction->amount,
     "created_at" => $now(),
     "updated_at" => $now(),
  ];
}

همه آن را به طور هم زمان در پایگاه داده وارد کنید

Transaction::insert($storeTransaction);

این رویکرد یک درج در پایگاه داده انجام می دهد. بنابراین به جای قرار دادن 10 – 15 بار ، تمام داده ها را به طور همزمان در پایگاه داده وارد کردید.

سناریو دو:
در صورت وجود ، شما یک عملکرد برای دریافت رکورد و به روزرسانی رکورد دارید.

اشتباه

public function updateTransactionStatus($id)
{
   $transaction = Transactions::where('id', $id)->get();

   if (!$transaction) {
         return $this->errorResponseHelper('fail', 'Transaction not found', 404);
   }

   Transactions::where('id', $id)->update(['status' => 1]);

   return $this->successResponseHelper('success', 'Transaction updated successfully', $transaction);
}

در حالی که این عملکرد خاص یا بلوک کد کار خود را به طور مؤثر انجام می دهد ، کارآمد نیست ، زیرا ما دو بار در حال واگذاری سوابق هستیم ، سپس یک تماس دیگر برای به روزرسانی ردیف/ضبط انجام می دهیم.

راه حل ساده برای این کار خواهد بود.

  • رکورد را با استفاده از بدست آوردن کلمه کلیدی
  • اگر رکورد وجود ندارد ، یک پیام خطا را برگردانید
  • اگر وجود دارد ، فقط از مدل یا سابقه ای که قبلاً برای به روزرسانی رکورد تماس گرفته اید استفاده کنید.
public function updateTransactionStatus($id)
{
   $transaction = Transactions::where('id', $id)->get();

   if (!$transaction) {
      return $this->errorResponseHelper('fail', 'Transaction not found', 404);
   }

   $transaction->update(['status' => 1]);

   return $this->successResponseHelper('success', 'Transaction updated successfully', $transaction);
}

کاری که شما در اینجا انجام داده اید کشتن دو یا سه پرنده با یک سنگ است.

اگر بلوک های کد مانند این را در پایگاه کد خود دارید ، وقت آن است که کد خود را بهینه کنید.

برنامه نویسی مبارک!

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا