В работе крупных баз данных «1С:Бухгалтерия 3.0» на платформе 8.3 иногда возникает критическая ситуация: стандартная обработка «Регистрация счетов-фактур на аванс» начинает работать крайне медленно или аварийно завершается. При анализе выясняется, что запрос, который должен выбирать данные всего за один день или месяц, фактически пытается прочитать все записи регистра за всю историю ведения учета. Рассмотрим подробно, почему это происходит и как решить проблему, даже если стандартное «Тестирование и исправление» не помогает из-за нехватки места на диске.
Когда мы указываем период в обработке, платформа 1С формирует запрос к виртуальным таблицам регистра бухгалтерии Хозрасчетный. В нормальных условиях СУБД использует индексы по дате и быстро выбирает нужные строки. Однако, если запрос «игнорирует» фильтр, это не значит, что в коде ошибка. Это означает, что планировщик запросов СУБД (PostgreSQL) решил, что выполнить полное сканирование таблицы (Full Scan) будет «дешевле», чем использовать индекс.
Проанализируем основные факторы, приводящие к такому поведению:
autovacuum), СУБД «не видит» выгоды в использовании индекса по дате.pgsql_tmp работа с ними становится невозможной, что ведет к ошибкам выполнения.Поскольку полное «Тестирование и исправление» в большой базе часто падает из-за нехватки ресурсов, мы можем выполнить пересчет итогов точечно. Разберем, как это сделать:
Перейдем в раздел «Функции для технического специалиста» (или «Все функции») и найдем стандартную обработку «Управление итогами». Проверим дату, по которую рассчитаны итоги по регистру бухгалтерии. Если она значительно отстает от текущей даты, установим период на начало текущего месяца и нажмем «Установить». Это действие гораздо менее ресурсоемкое, чем полное Т&И, так как система будет дозаписывать итоги только за недостающий период.
Если программный метод через интерфейс недоступен, можно попробовать выполнить установку периода итогов через код в консоли запросов:
РегистрыБухгалтерии.Хозрасчетный.УстановитьПериодРассчитанныхИтогов(КонецМесяца(ТекущаяДата()));
РегистрыБухгалтерии.Хозрасчетный.УстановитьПериодИтогов(КонецМесяца(ТекущаяДата()));
Если проблема сохраняется, значит, причина в «кривых» индексах или статистике на стороне СУБД. В этом случае нам нужно зайти в pgAdmin или консоль СУБД и выполнить регламентные операции для таблиц регистра бухгалтерии (обычно они начинаются с _accntreg).
Рассмотрим последовательность действий:
ANALYZE для всей базы или конкретных таблиц регистра. Это заставит PostgreSQL пересмотреть планы запросов.REINDEX TABLE [Имя_Таблицы] поможет пересобрать индексы, если они были повреждены или стали неэффективными. Внимание: для этого требуется свободное место на диске.VACUUM ANALYZE. Это освободит место внутри файлов БД от «мертвых» кортежей и обновит карту свободного пространства.Как отмечалось в обсуждении, ошибка часто возникает из-за того, что СУБД не может записать временные файлы. Даже если на основном диске есть 180 Гб, они могут быстро закончиться при выполнении тяжелого запроса к гигантскому регистру.
Посмотрим, что можно сделать:
CHECKPOINT и очистку логов (для PostgreSQL), чтобы высвободить место.01.01.0001 или 31.12.5999 могут сбивать алгоритмы расчета виртуальных таблиц. Попробуем найти их простым запросом:
ВЫБРАТЬ
Хозрасчетный.Период,
Хозрасчетный.Регистратор
ИЗ
РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный
ГДЕ
Хозрасчетный.Период < ДАТАВРЕМЯ(2000, 1, 1)
ИЛИ Хозрасчетный.Период > ДАТАВРЕМЯ(2030, 1, 1)
В некоторых случаях некорректный план запроса кэшируется не только в СУБД, но и на уровне сервера приложений 1С. Разберем процедуру очистки:
C:\Program Files\1cv8\srvinfo).snaccfg и reg_1541 (содержимое временных сеансовых данных).Проблема «игнорирования» периода в запросе — это комплексный симптом. Начните с управления итогами, так как это самая частая причина для виртуальных таблиц 1С. Если это не помогло, переходите к обслуживанию индексов и статистики в PostgreSQL. Обязательно обеспечьте СУБД достаточным объемом свободного места для временных файлов, иначе любые операции по восстановлению структуры базы будут завершаться ошибкой.