Штатный механизм запросов в платформе 1С:Предприятие 7.7 при работе с большими объемами данных часто работает медленно, особенно при расчете сложных отчетов по регистрам или выборке движений документов. Для ускорения обработки информации разработчики используют технологию прямых запросов к базе данных в обход встроенного движка платформы. Рассмотрим подробнее, какие компоненты и технологии подходят для реализации прямых запросов на MS SQL и DBF, а также разберем различия между ними.
Для серверных баз на MS SQL стандартом де-факто является бесплатная внешняя компонента 1С++ и ее ключевой класс ODBCRecordSet. Попытки использовать штатные объекты Windows вроде ADODB.Command на практике крайне неудобны, так как они не содержат механизма трансляции метаданных 1С.
Разберем основные преимущества использования ODBCRecordSet:
$Регистр.ОстаткиТоваров, $Справочник.Номенклатура) и виртуальные таблицы. Парсер автоматически заменяет их на реальные имена физических таблиц и колонок базы SQL.$РегистрОстатки, $РегистрОбороты и $РегистрОстаткиИОбороты сами генерируют оптимальный T-SQL код, соединяющий таблицы итогов и движений с корректным учетом точки актуальности (ТА).$ВидСправочника.Номенклатура) избавляют разработчика от необходимости вручную декодировать и кодировать ссылки формата Base36.ТаблицаЗначений или ИндексированнаяТаблица без медленного построчного обхода выборки.Посмотрим на типовой пример реализации прямого запроса через класс ODBCRecordSet компоненты 1С++:
ЗапросSQL = СоздатьОбъект("ODBCRecordSet");
ТекстЗапроса = "
|SELECT
| Рег.$Номенклатура AS [Номенклатура $Справочник.Номенклатура],
| Рег.$КоличествоОстаток AS [Количество]
|FROM
| $РегистрОстатки.ОстаткиТоваров(:ВыбДата~,,
| Номенклатура = :ВыбНоменклатура,
| (Номенклатура), (Количество)) AS Рег
|";
ЗапросSQL.УстановитьТекстовыйПараметр("ВыбДата", ТекущаяДата());
ЗапросSQL.УстановитьТекстовыйПараметр("ВыбНоменклатура", ВыбТовар);
ТабРезультат = СоздатьОбъект("ТаблицаЗначений");
Если ЗапросSQL.ВыполнитьИнструкцию(ТекстЗапроса, ТабРезультат) = 0 Тогда
Предупреждение("Ошибка выполнения прямого SQL-запроса!");
КонецЕсли;
В компоненте 1С++ реализована поддержка как ODBC, так и OLEDB. Однако на практике рекомендуется использовать именно ODBC по следующим причинам:
ODBCRecordSet максимально оптимизирован под работу с Microsoft SQL Server и стабильно функционирует на всех версиях платформы от SQL Server 2000 до современных версий.Проанализируем, как физически хранятся регистры в базе данных 1С 7.7 на MS SQL Server:
RG<ID>): хранит остатки на начало каждого месяца (расчетного периода) и на момент точки актуальности (ТА).RA<ID>): содержит записи каждого проведенного документа с реквизитами, ресурсами и служебными полями.DATE_TIME_IDDOC: составное служебное поле, включающее дату (8 символов), время со смещением (6 символов) и внутренний ID документа (9 символов).При выполнении прямых запросов к работающей рабочей базе важно избегать блокировок таблиц. Для этого в SQL-запросах рекомендуется использовать указание уровня изоляции без блокировок чтения или хинт WITH (NOLOCK).
Если разработка или тестирование ведется на файловой копии (DBF), инструмент ODBCRecordSet не подойдет в полной мере. Для файловых баз лучшим решением является внешняя компонента 1sqlite.
Особенности работы с 1sqlite:
.dbf как виртуальные таблицы.1sqlite отсутствуют виртуальные таблицы остатков платформенного уровня SQL (такие как $РегистрОстатки). Расчет остатков на произвольную дату требует ручного объединения таблиц итогов и движений через конструкции UNION ALL или предварительной подготовки срезов во временных таблицах в оперативной памяти (:memory:).Попытка писать код в файловой базе с расчетом на его перенос в MS SQL приводит к ряду проблем:
Вывод и рекомендация: если рабочая информационная база работает под управлением MS SQL Server, для разработки и тестирования необходимо развернуть локальный экземпляр MS SQL Server (например, бесплатную редакцию Express или Developer) и использовать связку 1С++ + ODBCRecordSet.