Как быстро очистить большие таблицы 1С через SQL и встроенный язык

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При работе с высоконагруженными базами данных на платформе 1С:Предприятие 8 часто возникает задача удаления огромного количества записей. Например, регистр сведений ВерсииОбъектов может раздуваться до десятков миллионов строк, что делает стандартное удаление через интерфейс или стандартные обработки неэффективным. В этой статье мы подробно разберем, как очищать данные быстро, не вызывая блокировок и обходя типичные заблуждения о работе сервера 1С.

Развенчание мифа об автоматическом откате изменений (Rollback)

Рассмотрим ситуацию, с которой сталкиваются многие начинающие администраторы: после удаления данных напрямую в SQL Management Studio данные чудесным образом «возвращаются» в 1С. Выясним причину этого явления. Сервер приложений 1С активно использует кеширование объектов и записей в оперативной памяти. Если вы выполняете команду DELETE или TRUNCATE на уровне СУБД, сервер 1С не получает об этом уведомления. Он продолжает хранить старые значения в своем кеше и выдает их пользователю при запросе.

Важно понимать: никакого автоматического «отката» со стороны 1С не существует. Платформа не следит за состоянием таблиц SQL в реальном времени. Чтобы изменения вступили в силу и стали видны в интерфейсе, необходимо либо перезапустить службу сервера 1С, либо программно сбросить кеш, либо дождаться его естественного обновления. Для чистоты эксперимента при работе с прямыми запросами рекомендуется выполнять операции в технологическое окно, когда активные сеансы пользователей завершены.

Способ 1: Очистка через пустой набор записей (Штатные средства)

Прежде чем переходить к прямым запросам, проанализируем самый быстрый штатный метод 1С. Вместо того чтобы перебирать записи в цикле и удалять их по одной (что крайне медленно), мы можем использовать механизм замещения набора записей.

Разберем пример кода для полной очистки регистра сведений: если же перед вами стоит задача очистить базу от данных только конкретной компании, для этого можно применить обработку для выборочного удаления организаций.


// Создаем пустой набор записей для регистра
Набор = РегистрыСведений.ВерсииОбъектов.СоздатьНаборЗаписей();

// Записываем его с параметром Замещать = Истина
// Платформа выполнит одну быструю транзакцию по удалению всех данных
Набор.Записать(Истина);

Этот метод работает значительно быстрее перебора, так как на уровне SQL формируется эффективный запрос. Однако для таблиц объемом в 10-20 миллионов записей даже этот способ может вызвать длительную блокировку таблицы и раздувание лога транзакций .LDF. В таких случаях мы переходим к инструментам СУБД.

Способ 2: Использование команды TRUNCATE TABLE

Если нам нужно очистить таблицу полностью, самым эффективным инструментом в MS SQL Server является команда TRUNCATE TABLE. В отличие от DELETE, эта команда не записывает удаление каждой строки в лог транзакций, а просто освобождает страницы данных.

Проанализируем шаги для выполнения этой операции изнутри 1С через ADODB:

  1. Выясним имя таблицы в SQL с помощью функции ПолучитьСтруктуруХраненияБазыДанных().
  2. Установим соединение с базой.
  3. Выполним команду.

// Получаем имя таблицы SQL для нашего регистра
Структура = ПолучитьСтруктуруХраненияБазыДанных();
// Находим нужную таблицу по имени метаданных
ИмяТаблицыSQL = "";
Для Каждого СтрокаСтруктуры Из Структура Цикл
    Если СтрокаСтруктуры.ИмяМетаданных = "РегистрСведений.ВерсииОбъектов" Тогда
        ИмяТаблицыSQL = СтрокаСтруктуры.ИмяТаблицы;
        Прервать;
    КонецЕсли;
КонецЦикла;

Если ЗначениеЗаполнено(ИмяТаблицыSQL) Тогда
    // Создаем COM-объект для связи с SQL
    Connection = Новый COMОбъект("ADODB.Connection");
    ConnectionString = "Provider=SQLOLEDB.1;Data Source=ИмяСервера;Initial Catalog=ИмяБазы;User ID=sa;Password=Пароль;";
    Connection.Open(ConnectionString);
    
    // Выполняем команду
    Connection.Execute("TRUNCATE TABLE " + ИмяТаблицыSQL);
    Connection.Close();
КонецЕсли;

Внимание: после выполнения TRUNCATE обязательно требуется очистить кеш сервера 1С, иначе вы будете видеть фантомные данные.

Способ 3: Порционное удаление данных (DELETE TOP)

Если задача стоит очистить данные выборочно (например, удалить только старые версии объектов до определенной даты), использование TRUNCATE невозможно, а обычный DELETE может «повесить» базу. В этой ситуации мы применим пакетное удаление.

Рассмотрим логику запроса, который удаляет данные порциями по 50 000 записей. Это позволяет логу транзакций успевать очищаться и не блокирует таблицу намертво: при работе с 1С:ERP для подобных задач можно использовать обработку для многопоточной свёртки и очистки базы.


WHILE 1=1
BEGIN
    DELETE TOP (50000) FROM _InfoRg12345 -- имя таблицы из структуры хранения
    WHERE _Fld54321 < '2023-01-01' -- условие по дате
    
    IF @@ROWCOUNT = 0 BREAK;
END

Такой подход позволяет выполнять очистку даже в рабочее время (при низком приоритете транзакций), так как между пакетами SQL Server может обрабатывать запросы других пользователей. При необходимости выборочной очистки без прямого доступа к СУБД можно использовать универсальную обработку для удаления и редактирования записей регистров сведений по фильтрам.

Как найти «битые» ссылки через SQL

Иногда очистка требуется не по дате, а по факту наличия «битых» ссылок (объектов, которые были удалены, но записи в регистрах остались). В SQL ссылки хранятся в формате binary(16). Чтобы найти такие записи, нам нужно выполнить LEFT JOIN таблицы регистра с таблицей объекта (например, справочника).

Посмотрим на пример логики поиска битых ссылок в регистре сведений:


SELECT MainTable.*
FROM _InfoRg123 AS MainTable
LEFT JOIN _Reference45 AS RefTable ON MainTable._Fld678RRef = RefTable._IDRRef
WHERE RefTable._IDRRef IS NULL

Здесь _Fld678RRef — это поле ссылки в регистре, а _IDRRef — уникальный идентификатор в таблице справочника. Если в справочнике записи нет (результат NULL), значит, ссылка «битая» и её можно удалять.

Важные рекомендации и итоги

Работа с базой данных напрямую через SQL — это мощный инструмент, требующий осторожности. Подведем итоги нашего исследования:

Проанализировав все способы, мы видим, что для большинства задач очистки больших объемов данных оптимальным является сочетание пакетного DELETE через ADODB и последующего регламентного обслуживания базы штатными средствами 1С.

← На главную