ה-SQL שלך מהיר אבל ה-API איטי

שאילתות מסד הנתונים שלך מהירות. המטמון (caching) שלך עובד. תהליכי הרקע (background jobs) שלך תקינים.

ובכל זאת, ה-API שלך עדיין איטי. ניצול ה-CPU שלך גבוה.

הבעיה היא לא מסד הנתונים שלך. הבעיה היא שכבת ה-Ruby.

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

  • סריאליזציה (serialization) מנופחת
  • הקצאת אובייקטים מוגזמת
  • חישובים חוזרים ונשנים

הנה איך לתקן אותן.

1. הפסק סריאליזציה מנופחת

מפתחים רבים הופכים מודלים שלמים ל-JSON.

render json: @shipments

אם למשלוח יש 40 עמודות אבל ה-frontend שלך זקוק רק ל-5, אתה מבזבז מחזורי CPU. אתה גם מסתכן בדליפת נתונים פרטיים כמו מפתחות API או עלויות.

הפתרון: החזר רק את השדות שאתה צריך.

render json: @shipments.as_json(only: [:id, :tracking_no, :status])

למהירות טובה עוד יותר, השתמש ב-pluck כדי לשלוף נתונים כמערכים. זה מונע לחלוטין בנייה של אובייקטי ActiveRecord כבדים.

2. צמצם הקצאת אובייקטים

כל אובייקט ש-Ruby יוצר עולה בזיכרון. יצירת אלפי אובייקטים במהלך בקשה בודדת מאלצת את ה-Garbage Collector (GC) לעבוד קשה יותר. זה מאט את המערכת כולה.

הימנע מבניית hashes או מחרוזות חדשות בתוך לולאות.

גרוע:

@shipments.map do |s|
  { label: "#{s.tracking_no} - #{s.status.upcase}" }
end

טוב: העבר נתונים סטטיים מחוץ ללולאה. בצע יותר עבודה במסד הנתונים במקום ב-Ruby.

3. הימנע מחישובים חוזרים ונשנים

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

דוגמה:

def total_weight
  shipments.sum(&:weight)
end

אם ה-view, ה-helper וה-serializer שלך כולם קוראים לזה, אתה מחשב את הסכום שלוש פעמים.

הפתרון: השתמש ב-memoization.

def total_weight
  @total_weight ||= shipments.sum(&:weight)
end

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

טבלת סיכום:

  • סריאליזציה מנופחת: החזר רק שדות נחוצים או השתמש ב-pluck.
  • הקצאה גבוהה: בנה פחות אובייקטים בתוך לולאות.
  • חישובים חוזרים ונשנים: השתמש ב-memoization כדי לעשות שימוש חוזר בתוצאות.

אופטימיזציה של מסד הנתונים פירושה לבקש פחות נתונים. אופטימיזציה של האפליקציה פירושה לבצע פחות "עבודת פרך" (busywork) ברגע שיש לך את הנתונים.

מקור: https://dev.to/danewu/your-sql-is-fast-but-the-api-is-slow-its-the-ruby-layer-2fno