Содержание:
- Как не допустить фатальных ошибок в системе 1C:Предприятие
- Описание типичных ошибок 1C‑разработчиков
Как не допустить фатальных ошибок в системе 1C:Предприятие
Каждый 1С-разработчик в своей карьере проходит через «минное поле» типовых ошибок, которые превращают быструю и отзывчивую систему в медленного и неповоротливого монстра. Хорошая новость в том, что большинство этих «мин» давно известны и изучены. Знание этих классических антипаттернов и умение их распознавать — ключевой навык, который позволяет писать эффективный код с самого начала.
Давайте разберем самые распространенные ошибки, которые съедают производительность, и научимся их избегать.
Описание типичных ошибок 1C‑разработчиков
Ошибка №1: Запросы в цикле (проблема N+1)
Это абсолютный чемпион по «убийству» производительности. Ошибку допускают даже опытные разработчики, когда теряют бдительность.
- Суть проблемы: Сначала одним запросом получается некая коллекция данных (например, список документов). Затем, при обходе этой коллекции в цикле, для каждого ее элемента выполняется еще один, отдельный запрос к базе данных (например, для получения остатка по товару из документа). В итоге вместо одного-двух запросов система генерирует N+1 запрос, где N — количество элементов в цикле. Накладные расходы на каждый сетевой обмен с СУБД колоссальны.
- Как это выглядит в коде:
// ПЛОХО: 1000 документов = 1001 запрос к базе!
Выборка = Запрос.Выполнить().Выбрать(); // 1-й запрос
Пока Выборка.Следующий() Цикл
// Для каждой строки запускается новый запрос
Остаток = ПолучитьТекущийОстаток(Выборка.Номенклатура); // N запросов
// …
КонецЦикла;
- Как исправить и избежать: Мыслите «пакетами». Соберите все необходимые данные одним или двумя сложными запросами, используя временные таблицы. Сначала получите все нужные номенклатурные позиции во временную таблицу, а затем одним запросом получите остатки для всех этих позиций.
Ошибка №2: Жадный ВЫБРАТЬ *
Простая, но очень коварная ошибка, которая проистекает из лени или небрежности.
- Суть проблемы: Использование * в запросе заставляет платформу и СУБД извлекать из таблиц абсолютно все поля, включая «тяжелые» реквизиты неограниченной длины, составные типы и хранилища значений. Даже если в коде вы используете только два поля из ста, система все равно проделает огромную лишнюю работу по чтению и передаче ненужных данных. Это перегружает диски, сеть и память.
// ПЛОХО
Запрос.Текст = “ВЫБРАТЬ * ИЗ Справочник.Контрагенты ГДЕ Код = &Код”;
// ХОРОШО
Запрос.Текст = “ВЫБРАТЬ Ссылка, Наименование, ИНН ИЗ Справочник.Контрагенты ГДЕ Код = &Код”;
// … далее следует установка параметра &Код и выполнение запроса
- Как исправить и избежать: Всегда явно перечисляйте только те поля, которые вам действительно нужны для решения конкретной задачи.
Ошибка №3: «Убийство» индексов функциям
Индексы — это основа скорости СУБД. Но их очень легко сделать бесполезными, написав запрос некорректно.
- Суть проблемы: Когда вы применяете какую-либо функцию к индексированному полю в условии ГДЕ, СУБД в большинстве случаев не может использовать индекс. Ей приходится последовательно считывать всю таблицу (выполнять Table Scan), применять функцию к каждой строке и только потом сравнивать результат.
- Как это выглядит в коде:
// ПЛОХО: Индекс по полю “Дата” не будет использоваться
ГДЕ ГОД(Документ.Дата) = 2023
// ПЛОХО: Индекс по полю “Артикул” не будет использоваться
ГДЕ ЛЕВ(Номенклатура.Артикул, 3) = “АБВ”
- Как исправить и избежать: Переписывайте условия так, чтобы они были SARGable (Search Argument Able), то есть «дружелюбными» к поиску по индексу. Модифицируйте не поле, а значение, с которым сравниваете.
// ХОРОШО: Индекс по дате будет работать
ГДЕ Документ.Дата МЕЖДУ ДАТАВРЕМЯ(2023, 1, 1) И ДАТАВРЕМЯ(2023, 12, 31, 23, 59, 59)
// ХОРОШО: Индекс по артикулу будет работать
ГДЕ Номенклатура.Артикул ПОДОБНО “АБВ%”
Ошибка №4: Неправильная работа с транзакциями
В многопользовательской среде эта ошибка приводит к взаимным блокировкам и простоям, когда пользователи буквально «замораживают» работу друг друга.
- Суть проблемы: Открытие транзакции на длительное время. Особенно опасно, когда внутри транзакции происходят интерактивные действия, требующие реакции пользователя (например, вывод вопроса Вопрос(…)). Пока пользователь думает над ответом, транзакция остается открытой, а захваченные ею ресурсы — заблокированными для всех остальных.
- Как исправить и избежать: Придерживайтесь железного правила: транзакция должна быть максимально короткой. Весь сбор данных, подготовка и диалоги с пользователем должны происходить ДО вызова НачатьТранзакцию(). Внутри транзакции — только запись данных и ничего больше.
Ошибка №5: Передача лишних данных на клиент
Эта ошибка делает интерфейс «медленным» и «неотзывчивым», особенно при работе через интернет.
- Суть проблемы: Выполнение на сервере запроса, который возвращает большую таблицу данных, и передача ее целиком на клиент для дальнейшей обработки (например, чтобы найти одно значение или посчитать итог). Это бессмысленная трата сетевых ресурсов и памяти на клиентской машине.
- Как исправить и избежать: Применяйте принцип «сервер для вычислений, клиент для отображения». Если вам нужен итог — посчитайте его в запросе на сервере. Если вам нужно одно значение — напишите серверную функцию, которая найдет его и вернет только его. Не тащите на клиент сырые данные.
Большинство проблем с производительностью в 1С имеют не мистическую, а вполне рукотворную природу. Выработав привычку избегать этих пяти классических ошибок, вы сможете значительно повысить качество своего кода. Помните: думать о производительности нужно не тогда, когда система уже «лежит» под нагрузкой, а на этапе написания каждой строки кода.
Специалист компании ООО “Кодерлайн”,
Радченко Степан
Добавить комментарий