При переносе информационных баз 1С:Предприятия 7.7 на клиент-серверный вариант (MS SQL Server) разработчики и системные администраторы нередко сталкиваются с ситуацией, когда открытие компактного справочника для выбора значения занимает от нескольких секунд до десятков секунд. Особенно ярко это проявляется при интерактивном вызове формы списка из документов или констант в терминальном режиме. Разберем по шагам, почему возникает эта задержка и как ее устранить.
Рассмотрим стандартный сценарий, при котором выполняется подбор расчетного счета организации. В типовых и доработанных конфигурациях код вызова диалога выбора в глобальном модуле обычно выглядит следующим образом:
РС = СоздатьОбъект("Справочник.БанковскиеСчета");
// Попытка позиционирования перед открытием
РС.НайтиЭлемент(Конт.РасчетныйСчет);
Если РС.Выбрать("Укажите расчетный счет", "ФормаСписка") = 1 Тогда
Конт.РасчетныйСчет = РС.ТекущийЭлемент();
КонецЕсли;
Выясним причину задержки. Если закомментировать строку с вызовом метода НайтиЭлемент(), форма списка открывается практически мгновенно. Однако при наличии предварительного поиска открытие списка замирает на несколько секунд. Замер производительности при этом показывает основное время ожидания именно на строке с методом Выбрать().
Проанализируем, как платформа 1С 7.7 взаимодействует с MS SQL Server в обоих случаях:
НайтиЭлемент() переводит внутренний контекст объекта на конкретную запись. Когда следом вызывается метод Выбрать("...", "ФормаСписка"), платформа пытается отобразить список так, чтобы найденный элемент сразу оказался в фокусе и в видимой области окна. Для этого через ODBC-драйвер задействуются API-курсоры СУБД (вызовы процедур sp_cursoropen и sp_cursorfetch). СУБД вынуждена рассчитывать относительное смещение бегунка полосы прокрутки и выбирать строки как выше, так и ниже текущей позиции. При неоптимальных индексах или особенностях сетевого стека это приводит к сканированию всей таблицы.Поскольку справочник расчетных счетов организации редко содержит более нескольких десятков или сотен строк, открывать тяжелую экранную форму с курсорами СУБД не имеет практического смысла. Оптимальным решением на уровне кода 1С является выгрузка доступных элементов во временный объект СписокЗначений и вызов простого интерфейса выбора.
Посмотрим на пример переписанного фрагмента кода:
СписокСчетов = СоздатьОбъект("СписокЗначений");
СпрСчета = СоздатьОбъект("Справочник.БанковскиеСчета");
// Инициализируем выборку счетов
СпрСчета.ВыбратьЭлементы();
Пока СпрСчета.ПолучитьЭлемент() = 1 Цикл
// Формируем понятное текстовое представление для выбора
Представление = СокрЛП(СпрСчета.НомерСчета) + " (" + СокрЛП(СпрСчета.Банк.Наименование) + ")";
СписокСчетов.ДобавитьЗначение(СпрСчета.ТекущийЭлемент(), Представление);
КонецЦикла;
ВыбЗначение = Конт.РасчетныйСчет;
Если СписокСчетов.ВыбратьЗначение(ВыбЗначение, "Укажите расчетный счет", , , 2) = 1 Тогда
Конт.РасчетныйСчет = ВыбЗначение;
КонецЕсли;
В этом варианте данные считываются последовательной быстрой выборкой без создания оконных таблиц и серверных курсоров. Метод ВыбратьЗначение() отображает легкое модальное окно, в котором сразу подсвечивается текущее значение, переданное в переменную ВыбЗначение.
Если терминальный сервер и сервер баз данных разнесены по разным машинам или работают под управлением устаревших версий операционных систем (например, Windows Server 2003), задержки при вызове курсоров часто связаны с протоколами именованных каналов.
В серверных ОС Windows Server 2003 SP2 и ранних выпусках Windows Server 2008 причиной микрозадержек на 2–5 секунд при передаче множества мелких пакетов часто выступает пакет Scalable Networking Pack (SNP).
Для устранения конфликтов сетевого драйвера с СУБД отключите разгрузку TCP через командную строку, запущенную от имени администратора:
netsh int ip set chimney DISABLED
После отключения аппаратного ускорения обработка потока мелких запросов ODBC курсора нормализуется.
Перевод базы на современные операционные системы (Windows Server 2012 и выше) и новые версии MS SQL Server устраняет проблемы сетевого стека прошлых лет, но требует учета системных ограничений платформы 1С 7.7:
BIN добавляют пустой файл-маркер ORDNoChk.prm.Max Degree of Parallelism = 1. Если этого не сделать, попытки оптимизатора СУБД распараллелить старые запросы 1С 7.7 будут приводить к частым взаимным блокировкам (дедлокам).1cv7s.exe необходимо внести в список исключений DEP во избежание внезапных падений программы при работе пользователей.