Как оптимизировать запросы к базе данных
Оптимизация запросов к базе данных ускоряет работу сайта, снижает нагрузку на сервер и помогает избежать сбоев при высокой посещаемости. Даже небольшие улучшения могут значительно повысить производительность.
Уменьшить количество запросов
Множественные запросы в цикле создают лишнюю нагрузку. Лучше собрать данные заранее и выполнить один запрос.
Пример запроса для товаров
-
Неправильный подход: выполнить запрос в цикле. Для каждого товара в корзине выполняется отдельный запрос к базе данных. Это неэффективно, так как количество запросов растет с увеличением числа товаров.
foreach ($arResult["ORDERS"] as $key => $val) { foreach ($val["BASKET_ITEMS"] as $vvval) { $rsEls = CIBlockElement::GetByID($vvval["PRODUCT_ID"]); // Запрос в цикле } } -
Правильный подход: собрать данные и выполнить один запрос. Сначала собрать все ID товаров в один массив. Затем выполнить один запрос к базе данных, чтобы получить данные всех товаров. Это значительно снижает нагрузку на сервер.
// Создаем массив для хранения ID товаров $arIDs = array(); // Перебираем заказы и товары в корзине foreach($arResult["ORDERS"] as $key => $val) { foreach($val["BASKET_ITEMS"] as $vvval) { // Добавляем ID товара в массив $arIDs[] = $vvval["PRODUCT_ID"]; } } // Если массив не пустой, выполняем один запрос if (!empty($arIDs)) { $rsEls = CIBlockElement::GetList( [], ["ID" => $arIDs], false, false, ["ID", "NAME"] ); // Наполняем данные, используя ID foreach($arResult["ORDERS"] as $key => $val) { foreach($val["BASKET_ITEMS"] as $vvval) { // Работа с данными } }
Использовать специализированные методы вместо универсальных
Универсальные методы подходят для широкого круга задач, но не учитывают их специфику. Это приводит к избыточному коду. Если есть специализированные методы для конкретных задач, используйте их. Специализированные методы уже содержат всю необходимую логику, что упрощает код и снижает вероятность ошибок.
Например, для изменения статуса оплаты заказа в модуле Интернет-магазин лучше использовать метод \Bitrix\Sale\Controller\Payment::setPaid, а не универсальный метод \Bitrix\Sale\Internals\Entity::setFields. Это гарантирует вызов всех необходимых обработчиков, связанных с оплатой.
Оптимизировать выборку данных
Заменить метод GetByID на GetList
Метод CIBlockElement::GetByID загружает все поля, даже если они не нужны. Используйте CIBlockElement::GetList, указывая только необходимые поля.
$rsEls = CIBlockElement::GetList(
[],
["ID" => $arIDs],
false,
false,
["ID", "NAME"] // Указываем только необходимые поля
);
В примере указываем, какие поля нужно получить из базы данных. Это уменьшает объем обрабатываемых данных и ускоряет выполнение запроса.
Оптимизировать основной запрос
Избегайте лишних запросов для получения связанных данных. Получайте все данные сразу, если это возможно.
// Получаем данные о книгах и авторах одним запросом
$rs = CIBlockElement::GetList(
['ID' => 'ASC'],
[
'IBLOCK_ID' => YY, // ID инфоблока
'ACTIVE' => 'Y'
],
false,
false,
[
'ID',
'NAME',
'PREVIEW_PICTURE',
'PREVIEW_TEXT',
'PROPERTY_AUTHOR.NAME', // Данные автора
'PROPERTY_AUTHOR.PREVIEW_PICTURE' // Фото автора
]
);
// Сохраняем результаты
while($ar = $rs->GetNext()) {
$arResult['ITEMS'][] = $ar;
}
Использовать точные фильтры вместо LIKE
Фильтр LIKE позволяет находить данные, которые частично совпадают с заданным значением. Фильтр использует специальный символ %, который заменяет любое количество других символов.
Если поиск по части строки не требуется, используйте вместо LIKE фильтры точного сравнения = или where. Это снизит нагрузку на сервер.
-
Пример фильтра
=:Bitrix\Iblock\ElementTable::getList([ 'select' => ['ID', 'NAME', 'CODE'], ['=CODE' => 'xxx'] ]);В примере мы используем точный фильтр
['=CODE' => 'xxx']и получаем данные только для элементов с конкретным значением поляCODE. -
Пример фильтра
where:Bitrix\Iblock\ElementTable::query() ->setSelect(['ID', 'NAME', 'CODE']) ->where('CODE','xxx')->exec();Здесь фильтр
where('CODE', 'xxx')отбирает элементы, у которых полеCODEравно'xxx'.
Создать поисковые индексы
Поисковый индекс — это структура данных, которая помогает базе данных быстрее находить нужную информацию. Без индексов поиск по большим таблицам может занимать много времени.
В каждом проекте медленные запросы зависят от структуры данных и частоты использования. Например, на сайте с большим количеством товаров медленным может быть запрос на поиск по цене и категории. В таких случаях помогает составной индекс, он создается сразу по нескольким полям таблицы.
Как определить, какие индексы нужны
Настроить монитор производительности
Монитор производительности — это инструмент, который помогает находить медленные запросы SQL.
-
Откройте административный раздел сайта.
-
Перейдите в Настройки > Настройки продукта > Настройки модулей > Монитор производительности.
-
Включите опцию «Записывать только медленные SQL-запросы».
-
Укажите время, после которого запрос считается медленным. По умолчанию это 0,1 секунды.
-
Установите время работы монитора. Рекомендуем запускать его на одни сутки.
-
Нажмите «Сохранить». Запустится монитор производительности. Через сутки вы сможете проанализировать медленные запросы.

Проанализировать результаты
После завершения работы монитора производительности:
-
Откройте административный раздел сайта.
-
Перейдите в Настройки > Производительность > Индексы > Анализ индексов.
-
Нажмите «Выполнить анализ собранных SQL-запросов».

В результатах обратите внимание:
-
на запросы с наибольшим временем выполнения,
-
запросы, которые выполняются чаще всего.
Не для каждого запроса нужно создавать индекс, так как это может увеличить нагрузку на базу данных. Иногда проблема в коде компонента. Например, если компонент делает слишком много запросов к базе данных, их можно оптимизировать.
Как создать индекс
Чтобы создать индекс для конкретного запроса:
-
Перейдите в Настройки > Производительность > Индексы > Анализ индексов.
-
Выберите нужный запрос, откройте меню и нажмите «Детальный анализ». Откроется страница с детальным анализом запроса.
-
Перейдите во вкладку «Создание индекса» и нажмите «Создать индекс».


Созданный индекс появится на странице Настройки > Производительность > Индексы > Список индексов. Проверьте его эффективность, выполнив повторный анализ запросов.
