Hunting N+1s and Killing Wasted Queries in Laravel

עבודה על ביצועים היא לרוב משעממת.

זה לא תמיד קשור לסיפורי גיבורים שבהם הפחתתם את השיהוי (latency) ב-80%. ברוב הימים, מדובר פשוט בניקוי. אתם מוצאים שאילתות שלא ידעתם שאתם מריצים. ואז, אתם מוחקים אותן.

אם אפליקציית ה-Laravel שלכם גדלה, סביר להניח שאתם נתקלים בשלוש הבעיות הללו.

  1. Hidden N+1 Queries

אי אפשר לתקן את מה שלא רואים. השתמשו בכלי כמו beyondcode/laravel-query-detector בסביבת הפיתוח המקומית שלכם. הוא יגיד לכם מתי אתם משתמשים בתבנית loop-and-lazy-load.

אל תריצו את זה ב-production. זה מוסיף overhead. רשמו (register) אותו רק כשהאפליקציה שלכם נמצאת במצב local או testing.

  1. Eager Loading Waste

אנשים נוהגים לפתור בעיות N+1 על ידי הוספת with(). אבל זה יוצר בעיה חדשה. אתם עלולים לבצע eager-load לקשר (relationship) שה-view שלכם כבר לא משתמש בו.

אם עיצוב מחדש מסיר עמודה מטבלה, עליכם להסיר את קריאת ה-with() המתאימה ב-controller שלכם. אתם משלמים על נתונים שאתם זורקים לפח.

התייחסו לכל eager load כאל דרישה (claim). אם אתם לא משתמשים בנתונים, הסירו את הדרישה.

  1. Recomputing the Same Data

ערכים מסוימים נשארים זהים לאורך כל ה-request. אם אתם מחשבים אותם מספר פעמים, אתם מבזבזים CPU. השתמשו ב-memoization כדי לפתור זאת.

Example:

protected ?string $defaultConnection = null;

public function getDefaultConnectionName(): string
{
    return $this->defaultConnection ??= $this->resolveDefaultConnection();
}

האופרטור ??= מחשב את הערך פעם אחת ומשתמש בו מחדש לשאר ה-request.

  1. Dashboard Query Traps

לוחות בקרה (Dashboards) מריצים לעיתים קרובות שאילתת count() נפרדת עבור כל כרטיס (card). אם יש לכם שישה כרטיסים, אתם מריצים שש שאילתות.

במקום זאת, עשו שני דברים:

  • קבצו את הספירות (counts) שלכם. קבלו את כל הסיכומים עבור טבלה אחת בשאילתה אחת.
  • השתמשו ב-cache קצר. סטטיסטיקות של לוח בקרה לא חייבות להיות מעודכנות בשנייה. שמרו אותן ב-cache למשך חמש דקות.

מבקר אחד משלם את מחיר השאילתה. כל השאר מקבלים את התוצאה מה-cache.

Final Tip: Prevent Regressions

תהליכי ניקוי נכשלים אם מפתחים מוסיפים מחדש את הקוד הגרוע מאוחר יותר. השתמשו ב-Pest כדי לבצע assertion לכמות השאילתות שלכם. הגדירו תקרה (ceiling) לכמות השאילתות שדף יכול להריץ. אם מפתח יוסיף N+1, הבדיקה תיכשל.

אופטימיזציה היא בעיקרה עניין של הסרה. הסירו טעינות שלא בשימוש. הסירו ערכים המחושבים מחדש. הסירו שאילתות מיותרות.

Source: https://dev.to/nasrulhazim/a-day-of-performance-hardening-hunting-n1s-and-killing-wasted-queries-in-laravel-568p