אופטימיזציה של 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 |
תוכנית אופטימיזציה שלב אחר שלב
- בצע ביקורת על בלוקי Highload. אסוף מבנה, נפחי נתונים, שאילתות אופייניות. הפעל לוג שאילתות איטיות.
- נתח צווארי בקבוק. זהה את 5 השאילתות האיטיות ביותר לפי זמן.
- הוסף אינדקסים. צור אינדקסים בודדים ומרוכבים עבור פילטרים בפועל.
- בצע רפקטורינג לקוד. החלף
$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, ]);ברשימה מפורשת, יישם מגבלות ופגינציה. - יישם קאש. השתמש בקאש מתויג עבור נתונים המבוקשים בתדירות גבוהה.
- פצל טבלאות. עבור טבלאות כרונולוגיות—פצל לפי תאריך.
- בצע בדיקות עומס. השוואת A/B של ביצועים לפני ואחרי.
מה כלול בעבודה
- ביקורת על בלוקי Highload: מבנה, נפח נתונים, שאילתות אופייניות ולוג שאילתות איטיות.
- ניתוח צווארי בקבוק: זיהוי 5 השאילתות האיטיות ביותר.
- הוספת אינדקסים: אינדקסים בודדים ומרוכבים עבור דפוסי פילטור אמיתיים.
- רפקטורינג לקוד: select מפורש, מגבלות, פגינציה, החלפת ORM ב-SQL ישיר במקומות שבהם זה נותן תועלת משמעותית.
- יישום קאש מתויג עבור בחירות כבדות.
- פיצול טבלאות כרונולוגיות (במידת הצורך).
- בדיקות עומס עם השוואת A/B לפני/אחרי.
- תיעוד והדרכה למפתח שלך.
לוח זמנים ותמחור
לוח זמנים לעבודה: ביקורת + אינדקסים + קאש — 2–3 שבועות. אופטימיזציה מלאה עם פיצול ורפקטורינג — 4–8 שבועות. העלות מחושבת באופן אישי לפי נפח נתונים ומורכבות. הצוות שלנו עם ניסיון רב שנים ב-Bitrix ולמעלה מ-50 פרויקטי אופטימיזציה שהושלמו מבטיח גישה שקופה ותוצאות מדידות. צור קשר להערכה מקדימה—נציע תוכנית עבודה עם נקודות ביקורת. הזמן ביקורת ביצועים וקבל ייעוץ מהנדס.
למידע נוסף על בלוקי Highload בתיעוד הרשמי.







