Как увеличить скорость работы 1С в 100 раз прямым обращением к MSSQL

от автора

Возникла задача пометить на удаление документы за 1 год. Эта операция выполняется перед бесследным удалением и включает выставление отметки и удаление движения по регистрам. Пробное удаление штатными средствами одного месяца заняло 4 часа. Это означало, что 12 месяцев удалялись бы 48 часов (2 суток). Забегая вперед, скажу, что прямым доступом к 1С документы удаляются за 30-40 минут. Обращение к MSSQL выполнялось через .Net framework и компонент .Net Bridge.

Определение имен таблиц MSSQL

Структура базы данных 1С весьма запутана и состоит из малозначимых для человека названий. 1С содержит функцию определения структуры хранения по имени объекта. В основу разработки положена эта функция ПолучитьСтруктуруХраненияБазыДанных, которая согласно русскому названию возвращает описание структуры. В этой структуре важны 2 поля Назначение, которое должно быть равно «Основная», и название таблицы ИмяТаблицыХранения.

Определение смещения дат

Таблица _YearOffset содержит число, обозначающее смещение года дат. Оно принимает значение 0 или 2000. Так со смещением 2000 дата 01.01.2014 будет храниться в базе данных как 01.01.4014. Соответственно при отборе по датам (удаление происходит за период времени) нужно учитывать смещение. Смещение можно получить следующим кодом 1С:

командаСмещение = sqlConnection.CreateCommand(); командаСмещение.CommandText = "select top 1 Offset from _YearOffset"; командаСмещение.CommandTimeout = timeout; чтениеСмещение = командаСмещение.ExecuteReader(); Если чтениеСмещение.Read() Тогда 	Смещение = чтениеСмещение.GetInt32(0); КонецЕсли; чтениеСмещение.Dispose(); 

Установка пометки на удаление документов

Имея названия таблиц документов и зная, что поля _Date_Time, _Marked и _Posted отвечают за дату, отметку об удалении и отметку о проведении соответственно, можно одним SQL-запросом пометить их все на удаление. Делается это так:

командаДокумента = sqlConnection.CreateCommand(); командаДокумента.CommandText = "UPDATE " + строкаТаблицы.ИмяТаблицыХранения + " SET _Marked = 0x01, _Posted = 0x00 WHERE _Date_Time BETWEEN @StartDate AND @EndDate"; командаДокумента.Parameters.AddWithValue("@StartDate", StartDate); командаДокумента.Parameters.AddWithValue("@EndDate", EndDate); командаДокумента.ExecuteNonQuery(); командаДокумента.Dispose(); 

Установка пометки на удаление в журналах документов

Не смотря на установку отметки на удаление у документов, в журналах документов хранятся дубли отметок об удалении на каждый документ. Список журналов, где участвует документ можно получить из метаданных документа так: Метаданные.ЖурналыДокументов
Отметка на удаление через поля _Marked и _Posted происходит аналогично через команду:

командаЖурналов.CommandText = командаЖурналов.CommandText + "UPDATE " + ОсновнаяТаблицаЖурнала + " SET _Marked = 0x01, _Posted = 0x00 WHERE _DocumentRRef IN (SELECT _IDRRef FROM " + строкаТаблицы.ИмяТаблицыХранения + " WHERE _Date_Time BETWEEN @StartDate AND @EndDate);" 

Удаление движений регистров

При удалении документов 1С удаляет движения документа по регистрам. В случае прямого доступа эти движения нужно удалить самостоятельно. Список регистров можно получить через метаданные ДокументМетаданные.Движения.
Команда, которой выполняется удаление движений следующая:

командаРегистров.CommandText = командаРегистров.CommandText + "DELETE FROM " + ОсновнаяТаблицаРегистра + " WHERE _RecorderRRef IN (SELECT _IDRRef FROM " + строкаТаблицы.ИмяТаблицыХранения + " WHERE _Date_Time BETWEEN @StartDate AND @EndDate);";  

Заключение

Как оказалось, добиться убыстрения работы 1С примерно на 2 порядка не так сложно, достаточно выполнить 3 вида команд. В конечной обработке логика расширена за счет выбора документов по видам, добавлением таймаута, добавлением транзакции, пакетным выполнением команд.

Саму обработку можно скачать здесь:
ПометкаУдаленияПрямымЗапросом.epf (13,77 kb)

ссылка на оригинал статьи http://habrahabr.ru/post/264687/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *