Запрос в консоли 1С завис: остановка, поиск причины и защита от повторения
Содержание
Чтобы прервать выполнение запроса в консоли запросов 1С, нажмите Ctrl+Break в окне клиента, где запущена консоль. Платформа прервёт выполнение кода и выдаст сообщение об ошибке, а данные базы останутся нетронутыми. Если окно не реагирует минуту и больше, остановку делают снаружи: завершают сеанс в консоли кластера серверов, а в крайнем случае отменяют запрос прямо в СУБД.
Способ выбирают по тому, где работает база и сколько ждать. Файловая база — только Ctrl+Break или снятие процесса клиента. Клиент-серверная — ещё консоль кластера и средства MS SQL или PostgreSQL. Всё сказанное относится к платформе 8.3 и не зависит от конфигурации: консоль запросов — это обработка, она одинаково работает в Бухгалтерии, ЗУП, УТ и любой другой базе.
Какой способ остановки выбрать
Сначала короткая карта. Двигайтесь сверху вниз: каждый следующий способ грубее и задевает больше людей.
| Способ | Когда применять | Что задевает |
|---|---|---|
Ctrl+Break в клиенте | Окно консоли живое, запрос идёт несколько минут | Только вашу операцию |
| Остановка отладки | Консоль запущена из Конфигуратора под отладчиком | Ваш сеанс предприятия |
| Завершение сеанса в «Активных пользователях» | Клиент завис, но есть второй вход с правами администратора | Ваш сеанс целиком |
| Завершение сеанса в консоли кластера | Клиент закрыт, а сервер продолжает работать | Ваш сеанс целиком |
| Отмена запроса в СУБД | Сеанс завершён, а нагрузка на SQL не уходит | Один запрос на стороне СУБД |
Перезапуск рабочего процесса rphost | Ничего не помогло, сервер встал | Все сеансы на этом процессе |
Последние две строки — инструмент администратора, а не бухгалтера. Завершение рабочего процесса обрывает работу всех пользователей, которых обслуживает этот процесс. Делайте это вне рабочего времени или после предупреждения коллег.
Стандартная остановка запроса: Ctrl+Break и закрытие клиента
Ctrl+Break
Комбинация Ctrl+Break прерывает выполнение кода встроенного языка в текущем сеансе. Консоль запросов выполняет запрос из кода, поэтому прерывание касается и её.
- Переключитесь в окно 1С, где висит консоль. Фокус должен быть именно на нём.
- Нажмите
Ctrl+Break. На ноутбуках без клавиши Break ищите сочетание сFn: часто этоCtrl+Fn+BилиCtrl+Fn+Pause, зависит от производителя. - Если платформа задаст вопрос о прерывании, подтвердите его.
- Дождитесь сообщения об ошибке выполнения. Это нормальный итог: запрос остановлен, данные базы не изменены.
Реакция бывает не мгновенной. Платформа проверяет запрос на прерывание между операциями, а один тяжёлый запрос к СУБД — это одна операция. Отмена до СУБД передаётся, но СУБД может закончить текущий шаг плана, прежде чем остановится. На больших таблицах это занимает от нескольких секунд до пары минут.
💡 Если выводите много строк, тормозить может не сам запрос, а заполнение табличного поля результата. Прерывание сработает и здесь, но в следующий раз поставьте ограничение на число выводимых строк.
Закрытие клиента
Когда окно перестало перерисовываться, остаётся закрыть процесс клиента через диспетчер задач: 1cv8c.exe для тонкого клиента
, 1cv8.exe для толстого.
В файловой базе снимайте процесс, только если консоль выполняла чтение. Если в обработке был запрос на изменение данных или запись объектов, принудительное закрытие во время записи может повредить файл 1Cv8.1CD. Перед повторным запуском сделайте копию каталога базы.
В клиент-серверной базе закрытие клиента не гарантирует остановку. Серверный вызов может продолжить работу в рабочем процессе, пока не закончит запрос. Поэтому после закрытия клиента проверьте сеанс в консоли кластера (раздел ниже).
Прерывание запроса в режиме предприятия и под отладчиком
Обычный запуск консоли в предприятии
Консоль запросов открывают через Файл → Открыть как внешнюю обработку
.epf или из списка дополнительных обработок. В обоих случаях запрос выполняется в вашем сеансе, и для его остановки годятся Ctrl+Break и завершение сеанса.
Некоторые консоли умеют выполнять запрос в фоновом задании. Тогда в форме есть своя кнопка отмены, а интерфейс не замерзает. Если у вашей консоли такая настройка есть, включите её: это самый удобный способ работать с тяжёлыми запросами.
Запуск под отладчиком из Конфигуратора
Если база открыта из Конфигуратора командой Отладка → Начать отладку, у вас есть два рычага в меню Отладка Конфигуратора:
- ⏸️ Прервать — останавливает выполнение кода на текущей строке, как точка останова. Помогает понять, где именно висит обработка: в самом запросе или в цикле после него.
- ⏹️ Завершить отладку — закрывает отлаживаемый сеанс предприятия целиком.
Команда прерывания срабатывает, только когда управление вернулось во встроенный язык. Пока выполняется метод Выполнить() объекта Запрос, отладчик ждёт его окончания. Поэтому на долгом запросе «Прервать» остановит код уже после того, как СУБД вернула результат.
💡 Под отладчиком удобно найти виновный пакет. Поставьте точку останова перед Запрос.ВыполнитьПакет(), выполните пакет и посмотрите, сколько строк вернул каждый временный запрос. Пакет, где вместо сотни строк получились миллионы, и есть место для правки.
Почему запрос в консоли выполняется бесконечно
Прервать запрос — половина дела. Если запустить тот же текст ещё раз, история повторится. Причины почти всегда в тексте запроса или в блокировках.
🔍 Типичные причины в тексте запроса:
- 🧮 Декартово произведение. Соединение без условия или с условием, которое пропускает почти все пары. Две таблицы по 50 000 строк дают 2,5 млрд строк.
- 📦 Виртуальная таблица без параметров.
ОстаткиИОборотыилиОборотырегистра без периода и отборов в параметрах читает всю историю регистра. - 🔗 Соединение с подзапросом. СУБД часто выбирает для него неудачный план. Помещение подзапроса во временную таблицу обычно ускоряет запрос в разы.
- 🌳 Условие
В ИЕРАРХИИиПОДОБНО "%…"по большим справочникам. Индекс здесь не помогает, идёт полный перебор. - 📝 Получение представлений. Обращение через точку к полям составного типа порождает множество соединений с таблицами всех возможных типов.
🔒 Причины вне текста:
- Запрос ждёт блокировку, которую держит чужая транзакция. Например, бухгалтер в этот момент перепроводит документы за квартал.
- Сервер СУБД перегружен закрытием месяца или резервным копированием.
- Устарела статистика СУБД, и планировщик выбирает плохой план.
Как проверить, что запрос ждёт, а не работает
В клиент-серверной базе откройте консоль кластера, найдите свой сеанс и посмотрите его свойства: там видно время текущего вызова и время ожидания блокировок. Если время вызова растёт, а нагрузка на процессор нулевая, запрос стоит в очереди на блокировку.
На стороне СУБД то же самое видно в системных представлениях. Для MS SQL Server:
SELECT session_id, status, wait_type, wait_time, blocking_session_id, total_elapsed_time
FROM sys.dm_exec_requests
WHERE session_id > 50;
Ненулевой blocking_session_id показывает, кто держит блокировку. Для PostgreSQL:
SELECT pid, state, wait_event_type, wait_event, now() - query_start AS duration, left(query, 100)
FROM pg_stat_activity
WHERE state <> 'idle'
ORDER BY duration DESC;
Строка с wait_event_type = 'Lock' — это ожидание блокировки.
Сокращение области данных: запрос, который не повиснет
Самый надёжный способ не прерывать запрос — сразу ограничить объём данных. Пока текст отлаживается, работайте на маленькой выборке и расширяйте её, когда результат правильный.
Приёмы ограничения выборки
ВЫБРАТЬ ПЕРВЫЕ 100. Ставьте в каждый новый запрос, пока проверяете логику. Убрать ограничение — дело одной секунды.- Период в параметрах виртуальной таблицы. Пишите
РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , Организация = &Организация), а не отбор вГДЕ. Условие в параметрах СУБД применяет до расчёта итогов. - Короткий период для проверки. Сначала день или неделя, потом месяц, потом год. Если неделя считается 10 секунд, год займёт минуты — и это повод оптимизировать заранее.
- Временные таблицы с индексом. Промежуточный результат кладите в
ПОМЕСТИТЬ, а поля, по которым дальше идёт соединение, указывайте вИНДЕКСИРОВАТЬ ПО. - Отказ от
ВЫРАЗИТЬна лету. Если поле составного типа нужно только для отбора одного типа, используйтеССЫЛКА Документ.РеализацияТоваровУслугв условии.
Пример: было и стало
Запрос, который медленно работает на базе за несколько лет:
ВЫБРАТЬ
Остатки.Номенклатура,
Остатки.КоличествоОстаток КАК Количество
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(&Дата) КАК Остатки
ГДЕ
Остатки.Склад = &Склад
Здесь платформа сначала рассчитывает остатки по всем складам организации, и только потом отбрасывает лишние строки. Правильный вариант переносит отбор в параметр виртуальной таблицы:
ВЫБРАТЬ ПЕРВЫЕ 100
Остатки.Номенклатура,
Остатки.КоличествоОстаток КАК Количество
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(&Дата, Склад = &Склад) КАК Остатки
УПОРЯДОЧИТЬ ПО
Количество УБЫВ
Имена регистра, измерений и ресурсов (ТоварыНаСкладах, Склад, КоличествоОстаток) здесь условные. Проверьте их в конструкторе запроса своей конфигурации: в разных типовых решениях регистры остатков названы по-разному.
Остановка запроса на сервере 1С и в СУБД
Этот раздел для администратора клиент-серверной базы. Любое завершение сеанса откатывает незаконченную транзакцию этого сеанса, а перезапуск рабочего процесса обрывает работу всех, кто на нём сидит.
Завершение сеанса из самой базы
В типовых конфигурациях на БСП есть список активных пользователей. В Бухгалтерии 3.0 и ЗУП 3.1 он находится в разделе Администрирование → Обслуживание. Откройте его из второго окна 1С, выделите свой зависший сеанс и завершите его командой формы. Нужны права администратора.
Консоль кластера серверов
- Запустите «Администрирование серверов 1С Предприятия».
- Раскройте
Кластеры → <ваш кластер> → Информационные базы → <база> → Сеансы. - Найдите сеанс по имени пользователя и компьютеру. В колонках видно время текущего вызова.
- Откройте контекстное меню сеанса и удалите его.
Из командной строки сеансы смотрят утилитой rac. Список кластеров даёт rac cluster list, список сеансов — rac session list с параметром кластера. Точные параметры завершения сеанса в вашей версии смотрите в справке rac help session.
Отмена в СУБД
Если сеанс 1С уже удалён, а СУБД продолжает считать, отмените запрос на её стороне.
MS SQL Server. Найдите session_id запроса из примера выше и выполните KILL <session_id>. Откат большой операции может занять столько же времени, сколько она шла.
PostgreSQL. Начинайте с мягкой отмены:
SELECT pg_cancel_backend(12345); -- отменить текущий запрос
SELECT pg_terminate_backend(12345); -- закрыть соединение, если отмена не помогла
Вместо 12345 подставьте pid из pg_stat_activity.
Убедитесь, что отменяете именно свой запрос. Рядом в списке висят соединения других пользователей и регламентных заданий, а по тексту запроса они похожи: 1С формирует имена таблиц вида _AccumRg1234, не Продажи.
Профилактика долгих выполнений
Несколько привычек, после которых прерывать запросы приходится редко.
Ещё три приёма, которые знает каждый, кто часто сидит в консоли:
- 🧪 Копия базы для экспериментов. Выгрузка
.dtи развёртывание тестовой базы занимают час, зато зависание никого не задевает. - 📈 Замер времени по пакетам. Многие консоли показывают время выполнения каждого запроса пакета. Самый медленный пакет — первый кандидат на правку.
- 🛠️ Регламентное обслуживание СУБД. Обновление статистики и перестроение индексов в MS SQL или
VACUUM ANALYZEв PostgreSQL возвращают планировщику адекватные планы. Это настраивает администратор сервера, обычно ночью.
В языке 1С у объекта Запрос нет свойства таймаута, поэтому ограничить время выполнения из самой консоли нельзя. Лимит времени можно задать на стороне СУБД, но это затронет всю базу, и такие настройки выставляет только администратор.