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

אופטימיזציה של בלוקים בעלי עומס גבוה: גישות וכלים תארו לעצמכם בלוק בעל עומס גבוה עם היסטוריית הזמנות של 5 מיליון שורות—שאילתה מסוננת לפי תאריך לוקחת **40 שניות**. לאחר אופטימיזציה—**8 אלפיות השנייה**. זה אפשרי עם אינדקסים נכונים, מטמון וחלוקה. בלוקים בעלי עומס גבוה (ה-`highlo
השירותים שאנו מציעים
מציג 1 מתוך 1כל 1626 השירותים
אופטימיזציה של בלוקים בעלי עומס גבוה: ביקורת, אינדקסים, מטמון, חלוקה
בינוני
~1-2 שבועות

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

שאלות נפוצות

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

  • image_website-b2b-advance_0.webp
    פיתוח אתר חברה B2B ADVANCE
    1460
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    פיתוח אתר לחברת FIXPER
    1019
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    פיתוח מבוסס Bitrix, Bitrix24, 1C לחברה פיתוח ווידג'ט להזמנת תורים אונליין למרכז רפואי
    763
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    פיתוח על בסיס 1C Enterprise עבור MIRSANBEL
    882
  • image_crm_dolbimby_434_0.webp
    פיתוח אתר על CRM Bitrix24 עבור DOLBIMBY
    809
  • image_crm_technotorgcomplex_453_0.webp
    פיתוח על בסיס Bitrix24 עבור חברת TECHNOTORGKOMPLEKS
    1164

אופטימיזציה של Highload-Block: גישות וכלים

דמיינו בלוק highload עם היסטוריית הזמנות של 5 מיליון שורות—שאילתה מסוננת לפי תאריך לוקחת 40 שניות. לאחר אופטימיזציה—8 מילישניות. זה ניתן להשגה עם אינדקסים נכונים, קאש ופיצול (partitioning). בלוקי highload (המודול highloadblock) הם מנגנון של Bitrix לאחסון נתונים שרירותיים בטבלאות נפרדות. מקרי שימוש נפוצים: לוגי אירועים, קטלוגי מוצרים עם מבנה לא סטנדרטי, פרופילי משתמשים, נתונים מצטברים (היסטוריית הזמנות, אנליטיקה, תורים). כל עוד השורות מתחת ל-50–100 אלף, הכל עובד מצוין. ב-1–10 מיליון שורות מתחילות בעיות: ה-ORM של Bitrix מייצר שאילתות לא אופטימליות, אינדקסים לא מכסים בחירות אמיתיות, JOINs מאטים. נתקלנו בפרויקטים שבהם זמן השאילתה היה 40 שניות—לאחר אופטימיזציה הוא ירד ל-8 מילישניות. חיסכון לכל שאילתה—עד 99.9%.

מדוע בלוקי highload מאטים על נתונים גדולים?

אנטי-דפוסים עיקריים בעבודה עם Highload:

  • אינדקסים נדרשים חסרים. בלוק highload יוצר טבלה עם מפתח ראשי ID ו-auto-increment. שדות מותאמים אישית כמו UF_* אינם מתווספים אוטומטית לאינדקס. שאילתת getList(['filter' => ['UF_PRODUCT_ID' => 123]]) על מיליון שורות היא סריקת טבלה מלאה.
  • שאילתות בסגנון SELECT *. כברירת מחדל, ה-ORM של Bitrix בוחר את כל השדות. אם לרשומה יש 30 שדות UF, כולל TEXT ו-FILE, זו שאילתה יקרה אפילו עם תוצאת סט קטנה.
  • שאילתות ללא הגבלה וללא פגינציה. DataManager::getList() ללא limit מחזיר את כל הרשומות לזיכרון PHP.
  • טבלאות מקושרות דרך Reference. אם Highload מקושר ל-Highload אחר או ל-infoblock דרך שדות Reference—ה-ORM בונה JOIN שהורג ביצועים ללא אינדקסים מתאימים.
  • עדכונים תכופים (UPDATE) על שדות ללא אינדקס. אופייני לשדות סטטוס, מוני ספירה.

כיצד לאבחן צווארי בקבוק?

הפעל את לוג השאילתות האיטיות של MySQL:

[mysqld] slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 1 log_queries_not_using_indexes = 1 

כיצד להוסיף אינדקסים נכון לטבלאות highload?

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

$connection = \Bitrix\Main\Application::getConnection(); $tableName = 'b_hl_product_catalog'; // Пример $connection->queryExecute( "CREATE INDEX IF NOT EXISTS idx_product_id ON {$tableName} (UF_PRODUCT_ID)" ); $connection->queryExecute( "CREATE INDEX IF NOT EXISTS idx_status_date ON {$tableName} (UF_STATUS, UF_DATE_CREATE)" ); 

מה אם ה-ORM עדיין מאט גם עם אינדקסים?

בחירה מפורשת של שדות נדרשים. לעולם אל תבקש [mysqld] slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 1 log_queries_not_using_indexes = 1 או מערך select ריק:

$result = ProductCatalogTable::getList([ 'select' => ['ID', 'UF_NAME', 'UF_PRICE', 'UF_ACTIVE'], 'filter' => ['UF_CATEGORY_ID' => $categoryId, 'UF_ACTIVE' => 1], 'order' => ['UF_SORT' => 'ASC'], 'limit' => 50, 'offset' => ($page - 1) * 50, ]); 

SQL ישיר לאגרגציה. עבור COUNT, SUM, GROUP BY על טבלאות גדולות—SQL ישיר מהיר פי 5–7 מה-ORM. השתמש ב-$connection = \Bitrix\Main\Application::getConnection(); $tableName = 'b_hl_product_catalog'; // Пример $connection->queryExecute( "CREATE INDEX IF NOT EXISTS idx_product_id ON {$tableName} (UF_PRODUCT_ID)" ); $connection->queryExecute( "CREATE INDEX IF NOT EXISTS idx_status_date ON {$tableName} (UF_STATUS, UF_DATE_CREATE)" ); .

פיצול (Partitioning) לנתונים כרונולוגיים. אם Highload מאחסן לוגים או אירועים עם תאריכים—פיצול לפי טווח תאריכים מאיץ משמעותית שאילתות תקופתיות:

ALTER TABLE b_hl_event_log PARTITION BY RANGE (YEAR(UF_DATE_CREATE) * 100 + MONTH(UF_DATE_CREATE)) ( PARTITION p_jan VALUES LESS THAN (202402), PARTITION p_feb VALUES LESS THAN (202403), PARTITION p_future VALUES LESS THAN MAXVALUE ); 

קאש של תוצאות. נתוני Highload נשמרים היטב בקאש דרך select: ['*'] עם תיוג. דוגמת יישום:

class CachedProductCatalog { private const CACHE_TAG = 'hl_product_catalog'; private const CACHE_TTL = 3600; public function getByCategory(int $categoryId): array { $cache = \Bitrix\Main\Data\Cache::createInstance(); $cacheKey = 'hl_catalog_cat_' . $categoryId; if ($cache->initCache(self::CACHE_TTL, $cacheKey, '/hl/catalog/')) { return $cache->getVars(); } $cache->startDataCache(); // Fetch from DB $result = $this->fetchFromDb($categoryId); // Тегированный кеш $tagCache = new \Bitrix\Main\Data\TaggedCache(); $tagCache->startTagCache('/hl/catalog/'); $tagCache->registerTag(self::CACHE_TAG . '_' . $categoryId); $tagCache->endTagCache(); $cache->endDataCache($result); return $result; } } 

מדדים: מה כל אופטימיזציה נותנת

אופטימיזציה טבלת 1M שורות טבלת 10M שורות
הוספת אינדקס על שדה מסונן 4000 ms → 5 ms 40000 ms → 8 ms
בחירת שדות נדרשים בלבד 800 ms → 120 ms
פגיעת קאש 120 ms → 0.5 ms
SQL ישיר במקום ORM (אגרגציה) 350 ms → 45 ms 3000 ms → 80 ms
פיצול לפי תאריך 3000 ms → 60 ms

תוכנית אופטימיזציה שלב אחר שלב

  1. בצע ביקורת על בלוקי Highload. אסוף מבנה, נפחי נתונים, שאילתות אופייניות. הפעל לוג שאילתות איטיות.
  2. נתח צווארי בקבוק. זהה את 5 השאילתות האיטיות ביותר לפי זמן.
  3. הוסף אינדקסים. צור אינדקסים בודדים ומרוכבים עבור פילטרים בפועל.
  4. בצע רפקטורינג לקוד. החלף $result = ProductCatalogTable::getList([ 'select' => ['ID', 'UF_NAME', 'UF_PRICE', 'UF_ACTIVE'], 'filter' => ['UF_CATEGORY_ID' => $categoryId, 'UF_ACTIVE' => 1], 'order' => ['UF_SORT' => 'ASC'], 'limit' => 50, 'offset' => ($page - 1) * 50, ]); ברשימה מפורשת, יישם מגבלות ופגינציה.
  5. יישם קאש. השתמש בקאש מתויג עבור נתונים המבוקשים בתדירות גבוהה.
  6. פצל טבלאות. עבור טבלאות כרונולוגיות—פצל לפי תאריך.
  7. בצע בדיקות עומס. השוואת A/B של ביצועים לפני ואחרי.

מה כלול בעבודה

  • ביקורת על בלוקי Highload: מבנה, נפח נתונים, שאילתות אופייניות ולוג שאילתות איטיות.
  • ניתוח צווארי בקבוק: זיהוי 5 השאילתות האיטיות ביותר.
  • הוספת אינדקסים: אינדקסים בודדים ומרוכבים עבור דפוסי פילטור אמיתיים.
  • רפקטורינג לקוד: select מפורש, מגבלות, פגינציה, החלפת ORM ב-SQL ישיר במקומות שבהם זה נותן תועלת משמעותית.
  • יישום קאש מתויג עבור בחירות כבדות.
  • פיצול טבלאות כרונולוגיות (במידת הצורך).
  • בדיקות עומס עם השוואת A/B לפני/אחרי.
  • תיעוד והדרכה למפתח שלך.

לוח זמנים ותמחור

לוח זמנים לעבודה: ביקורת + אינדקסים + קאש — 2–3 שבועות. אופטימיזציה מלאה עם פיצול ורפקטורינג — 4–8 שבועות. העלות מחושבת באופן אישי לפי נפח נתונים ומורכבות. הצוות שלנו עם ניסיון רב שנים ב-Bitrix ולמעלה מ-50 פרויקטי אופטימיזציה שהושלמו מבטיח גישה שקופה ותוצאות מדידות. צור קשר להערכה מקדימה—נציע תוכנית עבודה עם נקודות ביקורת. הזמן ביקורת ביצועים וקבל ייעוץ מהנדס.

למידע נוסף על בלוקי Highload בתיעוד הרשמי.