Оптимізація імпорту великих обсягів даних 1С-Bitrix
Стандартний обмін з 1С через CommerceML обробляє 50 000 товарів за 4 години. Для каталогу з 200 000 позицій з 30 властивостями та 5 типами цін — обмін не завершується взагалі: упирається в max_execution_time, вичерпує пам'ять або блокує таблиці на години. Оптимізація імпорту — це робота на трьох рівнях: налаштування PHP та БД, доробка процедури обміну та перехід на інкрементальний імпорт.
Чому стандартний обмін гальмує
CommerceML-обмін працює так: 1С вивантажує повний XML-файл (import.xml + offers.xml), Bitrix парсить його та для кожного елемента викликає CIBlockElement::Add() або CIBlockElement::Update(). Кожен виклик:
- Перевіряє права доступу
- Викликає обробники подій
OnBefore* - Записує елемент в
b_iblock_element - Записує властивості в
b_iblock_element_property(окремий INSERT/UPDATE для кожної властивості) - Записує ціни в
b_catalog_price - Оновлює індекс пошуку
- Інвалідує кеш
- Викликає обробники
OnAfter*
На один елемент — 10–20 SQL-запитів. Для 200 000 елементів — 2–4 мільйони запитів. Плюс пересоздання фасетного індексу на кожне зміною.
Налаштування PHP
| Параметр | Значення для імпорту | За замовчуванням |
|---|---|---|
max_execution_time |
0 (без обмеження) | 30 |
memory_limit |
2048M | 128M |
post_max_size |
200M | 8M |
upload_max_filesize |
200M | 2M |
Ці параметри задаються або глобально в php.ini, або для конкретного скрипту обміну через .htaccess або віртуальний хост. Для PHP-FPM — через окремий пул з збільшеними ліметами для URL /bitrix/admin/1c_exchange.php.
Налаштування MySQL
Під час імпорту:
-
Вимкнення
sync_binlog(якщо не використовується репліцювання) — кожен INSERT не буде синхронно записуватися на диск:SET GLOBAL sync_binlog = 0; -
Збільшення
innodb_log_file_sizeдо 1–2 ГБ — зменшує частоту checkpoint та прискорює запис -
innodb_flush_log_at_trx_commit = 2— запис лога трансакцій раз на секунду замість кожної трансакції -
innodb_autoinc_lock_mode = 2— прискорює bulk INSERT (interleaved lock)
Після імпорту поверніть налаштування до боєвих значень. Для автоматизації — скрипт-обгортка, який змінює параметри перед імпортом та повертає після.
Вимкнення обробників та індексів
Головний прискорювач — вимкнення непотрібної роботи на час імпорту:
-
Обробники подій. Якщо на
OnAfterIBlockElementUpdateвисить відправка сповіщень або оновлення зовнішної системи — при імпорті 200 000 товарів це 200 000 HTTP-запитів. Вимкніть через флаг: перевіряйтеdefined('CATALOG_IMPORT_RUNNING')в обробнику. -
Індекс пошуку. Вимкнути модуль
searchна час імпорту:\Bitrix\Main\ModuleManager::deActivate('search')— радикально, але ефективно. Альтернатива — вимкнути індексацію інфоблока каталогу в налаштуваннях модуля пошуку. - Фасетний індекс. Пересоздання при кожному оновленні товара — безсмисловно при масовому імпорті. Вимкніть автоматичне оновлення, після імпорту запустіть пересоздання один раз.
-
URL-транслітерація та генерація ЧПУ. Якщо
CODEгенерується при збереженні елемента — це додаткові обчислення. ПередавайтеCODEз 1С або генеруйте пакетно після імпорту.
Пакетний імпорт через D7 API
Замість поелементного CIBlockElement::Update() — пряма робота з таблицями через D7 ORM:
// Пакетне оновлення цін
$connection = Application::getConnection();
$connection->queryExecute("
INSERT INTO b_catalog_price (PRODUCT_ID, CATALOG_GROUP_ID, PRICE, CURRENCY)
VALUES (1, 1, 100.00, 'RUB'), (2, 1, 200.00, 'RUB'), ...
ON DUPLICATE KEY UPDATE PRICE = VALUES(PRICE), CURRENCY = VALUES(CURRENCY)
");
INSERT ... ON DUPLICATE KEY UPDATE дозволяє оновлювати пакетами по 1000 рядків за один запит замість 1000 окремих UPDATE. Прискорення — у 10–50 разів.
Обмеження: при прямому записі в таблиці обробники подій не викликаються, кеш не інвалідується, фасетний індекс не оновлюється. Все це потрібно зробити вручну після імпорту.
Інкрементальний імпорт
Повний імпорт 200 000 товарів щокожної ночі — розточительство, якщо змінилося 500 позицій. Інкрементальний підхід:
- На стороні 1С — вивантажувати тільки змінені елементи (за датою модифікації)
- На стороні Bitrix — приймати дельту через REST API або кастомний endpoint
- Порівняння хешів — для кожного товара зберігати MD5 від набору ключових полів. При імпорті зіставляти хеш — якщо не змінився, пропускати
Для проектів з обміном частіше раза на годину інкрементальний імпорт — єдиний робочий варіант.
Моніторинг та діагностика
-
Лог імпорту — Bitrix пише в
/bitrix/catalog_export/. Аналізуйте час кожного кроку. -
Slow query log — включіть в MySQL на час імпорту (
long_query_time = 1). Показує проблемні запити. -
Профілювання —
Bitrix\Main\Diag\SqlTrackerрахує кількість та час SQL-запитів. Включіть на тестовому прогоні, знайдіть вузькі місця.
Терміни оптимізації
| Завдання | Ефект | Термін |
|---|---|---|
| Налаштування PHP + MySQL + вимкнення обробників | Прискорення у 2–5 разів | 1–2 дні |
| Пакетний імпорт через прямі SQL-запити | Прискорення у 10–50 разів | 3–5 днів |
| Інкрементальний імпорт (дельта + хеші) | Імпорт за хвилини замість годин | 1–1.5 тижня |
| Повний комплекс (усі три рівні + моніторинг) | Каталог 200K+ працює штатно | 1.5–2 тижні |
Ключовий принцип: стандартний обмін CommerceML — це зручність розробки ціною продуктивності. Для каталогів понад 50 000 товарів потрібно усвідомлено вирішувати, де стандартний механізм прийнятний, а де — прямий SQL та інкрементальна логіка.







