האצת מסד נתונים באפליקציית מובייל: אינדקסים, N+1, הקשרי רקע

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

פיתוח ותמיכה בכל סוגי היישומים הניידים:

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

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

השירותים שאנו מציעים
מציג 1 מתוך 1כל 1734 השירותים
האצת מסד נתונים באפליקציית מובייל: אינדקסים, N+1, הקשרי רקע
בינוני
~2-3 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית מובייל עבור FEEDME
    פיתוח אפליקציית מובייל עבור FEEDME
    971
  • פיתוח אפליקציית מובייל עבור XOOMER
    פיתוח אפליקציית מובייל עבור XOOMER
    868
  • פיתוח אפליקציית מובייל עבור RHL
    פיתוח אפליקציית מובייל עבור RHL
    1288
  • פיתוח אפליקציית מובייל עבור ZIPPY
    פיתוח אפליקציית מובייל עבור ZIPPY
    1143
  • פיתוח אפליקציית מובייל עבור Affhome
    פיתוח אפליקציית מובייל עבור Affhome
    1076
  • פיתוח אפליקציית מובייל עבור חברת FLAVORS
    פיתוח אפליקציית מובייל עבור חברת FLAVORS
    677

אופטימיזציה של מסד נתונים באפליקציית מובייל: איפה המהירות נשברת

האחסון המקומי — SQLite או עטיפה מעליו — הופך לצוואר בקבוק בשכבת הנתונים לפני הרשת והרינדור. כל עוד יש עשרות רשומות, הכול מגיב מיד; בנפחים אמיתיים ההשהיה לפני רינדור המסך גדלה פי כמה, ותקיעות בגלילה ברשימה בדרך כלל תולות בתמונות כבדות.

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

השנייה — פניות מיותרות בלולאה, N+1 קלאסי. מתאם הרשימה מבקש נתונים קשורים עבור כל פריט בנפרד: מאה כרטיסים הופכים למאה שאילתות, כל אחת עם טרנזקציה והכנת ביטוי משל עצמה. שאילתת אצווה אחת לפי קבוצת מזהים פותרת את אותה משימה בפנייה אחת.

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

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

אפקט מדיד: תגובת מסכים, זיכרון וצריכת סוללה

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

התרומה העיקרית ניתנת מארגון מחדש של העבודה עם SQLite המוטמע. מפל שאילתות לכל שורת רשימה מוחלף בחיבור אחד, לשליפות תכופות מתווספים אינדקסים מורכבים, קריאות כבדות עוברות להקשר רקע. זמן פתיחת המדור מצטמצם מ-1.5 שניות ל-0.2, הגלילה מתבצעת ללא פריימים מוחמצים אפילו במכשירים חלשים.

נפח האחסון מפסיק לגדול כאשר למטמון יש מדיניות אחסון: רשומות ישנות נארכבות ונדחסות, שליפות ביניים אינן שוקעות בדיסק. צריכת הסוללה ברקע יורדת לאחר קיבוץ משימות רקע — האפליקציה מפסיקה להתעורר כל כמה שניות לצורך סנכרון.

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

אפשרויות האצה: אינדוקס, סכימת אחסון, פעולות רקע

האצה כמעט תמיד נתקעת לא במנוע, אלא באופן שבו האפליקציה מדברת איתו. רוב מסדי הנתונים למובייל — אלה SQLite או תוספת אובייקטים מעליו, ושאילתות שנכתבו „כמו בקוד שרת” עולות בטלפון פי כמה. להלן חלופות שבאמת בוחרים ביניהן, והמגבלות שלהן.

אפשרות מתי מתאימה מגבלות
אינדוקס שליפות איטיות לפי שדות מסוימים, סינון ומיון ברשימות מאט הכנסה ועדכון, תופס מקום בקובץ מסד הנתונים; אינדקסים מיותרים נותנים אפקט הפוך
שינוי סכימת האחסון נתונים נאספים מהרבה טבלאות קשורות, הרבה שדות נדירים נדרשת מיגרציה וניהול גרסאות לסכימה, בהרצה ראשונה על מסד גדול — השהיה
טעינת אצווה של נתונים המסך מבצע עשרות שאילתות מאותו סוג בלולאה במקום אחת דורשת תנאי שליפה מדויקים: אצווה רחבה מדי מושכת מיותר
מטמון תוצאות אותם רשימות נפתחות לעיתים קרובות, צבירים מחושבים מחדש בכל פעם נדרשת פסילה לפי אירועי כתיבה, אחרת המשתמש רואה נתונים מיושנים
פעולות רקע כתיבה, סנכרון וצבירים כבדים חוסמים את הממשק נדרש בקרת גישה מקבילה להקשר הכתיבה וטיפול נכון בביטול

כיצד משלבים זאת

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

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

שלבי העבודה: מאבחון ועד מסירת נהלים

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

  1. אבחון צווארי בקבוק. מבצעים מדידות על הבנייה הנוכחית: התחלה קרה, תגובת מסכים כבדים, תדירות ומשך הפניות לאחסון המקומי. את הפרופיל שומרים כנקודת ייחוס — בהמשך משווים רק אליו.

  2. ניתוח הפניות לנתונים. עוברים על מסכים ותרחישים, מחפשים שאילתות N+1, כפילויות קריאה, שליפות בלי אינדקסים, עבודה עם האחסון בתהליכון הראשי. כל חשד מאמתים בפרופיל, לא בניחוש.

  3. תוכנית שינויים. מתעדים את הרכב האינדקסים, ניסוחי השאילתות, הפרדה בין הקשרי רקע, סדר מיגרציית הסכימה. מתאמים לפני התיקונים, כדי שהיקף העבודה והסיכונים יהיו ברורים מראש.

  4. כיוונון. מכניסים את השינויים שלב אחר שלב, כל אחד — בנפרד ועם המדידה שלו: רואים מה נתן אפקט ומה לא.

  5. בדיקה על נתונים אמיתיים. מריצים תרחישים על עותק של מסד העבודה ועל מכשירים חלשים: התחלה קרה, נפח היסטוריה גדול, מיגרציה מהגרסה הקודמת. מסתכלים לא על הממוצע, אלא על המקרה הגרוע.

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

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

מה נשאר אצלכם: תוצרים, סכימות ונהלים

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

  • מפת סכימת האחסון — טבלאות, קשרים, מפתחות, נפחים וקצב גדילה לכל אחסון. רואים אילו שליפות יהפכו לכבדות לאחר גידול הנתונים, ומה לעשות עם זה מראש.
  • תיאור אינדקסים — לאיזו שאילתה נוצר כל אחד, מאילו שדות מורכב, איזו שליפה הוא מכסה. בנפרד מסומנים אינדקסים שמאיצים קריאה אבל מאטים הכנסה.
  • ניתוח מפלי שאילתות — היכן האפליקציה, במקום שליפה אחת, פנתה למסד بعשרות פניות, ובמה זה הוחלף.
  • נוהל תחזוקה — תדירות הבדיקות, סדר מיגרציות הסכימה וכללי חזרה לאחור, אם עדכון נכשל בחלק מהמכשירים.
  • רשימת בדיקות לפני שחרור — מדידות על נתונים אמיתיים: זמן פתיחת מסך כבד, מספר קריאות, גודל קובץ מסד הנתונים.
  • כללים לעבודה עם משימות רקע — מה מותר כשהאפליקציה עוברת לרקע, מה לדחות ואיך לא לאבד פעולה בעת מזעור.
  • הנחיות לצוות — לאן להסתכל בתלונה „זה איטי”, איך לבצע מדידת ביצועים ומה נחשב לנורמה עבור מסך.

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

מקרה בוחן: כיצד הסרנו תקיעות בשליפות גדולות

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

על סט בדיקה של 500 רשומות התגובה הייתה מיידית, על נתונים אמיתיים — 40–60 אלף פריטים במדור — הפתיחה ארכה 4–6 שניות, והסנכרון הוסיף רשומות לאותן טרנזקציות כמו הקריאה.

עם מה הגענו

המדור נפתח 4–6 שניות, במכשירים חלשים — עד 9. שיעור הפניות לתמיכה עם הניסוח „נתקע, לא נפתח” החזיק מעמד על 18% מכלל הפניות. צרה נפרדת — כשלים בסנכרון: בזמן שהמשתמש קרא את הרשימה, עדכון רקע דרס שינויים מקומיים, והוא ראה נתונים מיושנים.

מה שינינו

אינדקסים הרכיבו לפי השאילתות בפועל: אחד מורכב לפי מפתחות הסינון והמיון במקום שלושה בודדים. הסרנו N+1 — במקום שליפה בלולאה עבור כל כרטיס מתבצעת שאילתת אצווה אחת. קריאות כבדות הועברו להקשר רקע, כתיבת הסנכרון — לתור סדרתי יחיד, ולכן קריאה וכתיבה כבר לא מצטלבות באותה טרנזקציה. הרשימה הועברה לטעינה מדורגת של 50 פריטים בכל עמוד.

פתיחת המדור כעת 0.4–0.7 שניות, שיעור התלונות על תקיעות ירד מ-18% ל-3%, וסוג הכשלים „הסנכרון דרס נתונים מקומיים” נסגר לחלוטין: במשך שלושה חודשי ניטור — אף מקרה.

במה שונה אינדוקס מבנייה מחדש של סכימת האחסון?

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

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

אינדקסים מכסים את רוב המקרים: אם שאילתה הפסיקה לסרוק את כל הטבלה ועוברת לפי תנאים מסוימים, אין צורך לגעת בסכימה. אינדקס מתווסף בלי העברת נתונים ושומר על תאימות לאחור — גרסאות ישנות של האפליקציה קוראות את אותו מסד.

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

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

ספקות טכניים נפוצים לפני תחילת העבודה

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

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

האם נדרש ריפקטורינג מלא של שכבת הנתונים?

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

מה לעשות עם הנפחים שכבר הצטברו?

מעבירים במיגרציית רקע עמוד אחר עמוד, עם נקודת חידוש וחזרה על הפעולה בעת קטיעה. האפליקציה ממשיכה לעבוד על הנתונים הנוכחיים — מצב „חצי-מועבר” לא נוצר.

האם מכשירים ישנים ייכשלו?

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

עד כמה התיקונים בטוחים וכמה זמן ייקחו?

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

נדון במשימה ונחזור עם הערכה ותוכנית

כדי להציע הערכה ריאלית לאופטימיזציה של מסד נתונים באפליקציית מובייל, ולא אומדן „בעין”, אנחנו צריכים הקשר: סכימת הנתונים, מסכים כבדים ואיך האפליקציה מתנהגת במכשירים חלשים ובקישוריות גרועה. להלן — מה אנחנו מבקשים בקלט ומה מחזירים בתשובה.

מה נדרש מצדכם כדי להתחיל:

  • קוד מקור עם הענף הנוכחי — עם הרשאת קריאה, בלי מסירת מפתחות חתימה וסודות סביבת הייצור.
  • סכימת מסד הנתונים והמיגרציות: גרסת סכימה, הרכב אינדקסים, נפח טבלאות ופיזור רשומות.
  • 3-5 התרחישים האיטיים ביותר: מסך, פעולת משתמש ומה בדיוק מאט — פתיחת רשימה, חיפוש, סנכרון.
  • עמדת בדיקה או סט נתונים אנונימי, שעליו הבעיה משוחזרת באופן יציב.
  • גישה לאמצעי מדידה: יומנים, דוחות שגיאות, ואם יש — מעקבי שאילתות.
  • איש קשר של מהנדס שמכיר את מודל הנתונים ואת היסטוריית ההחלטות לגבי שכבת האחסון.

מה אנחנו מחזירים אחרי הניתוח:

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

תארו את המשימה — נחזור עם הערכה ותוכנית ונתאם את תאריך תחילת הפרויקט.