При интеграции систем контроля доступа (СКУД) с 1С через COMОбъект разработчики часто сталкиваются с критической ошибкой [Microsoft][ODBC SQL Server Driver]Истекло время ожидания запроса. Давайте разберем по шагам, почему это происходит и как построить архитектуру обмена данными, чтобы отчеты формировались быстро и корректно.
Чаще всего причина падения запроса по таймауту кроется не в самом соединении, а в неоптимальном тексте SQL-запроса. В исходном примере использовалась конструкция FROM pLogData, pList. В терминах баз данных это приводит к созданию декартового произведения. Если в таблице логов 100 000 записей, а в списке сотрудников 500, сервер пытается сначала сгенерировать 50 000 000 строк, и только потом применяет фильтр по условию WHERE. Это гарантированно «вешает» сервер при больших объемах данных.
Также на скорость влияют:
LIKE с символом % в начале: Это заставляет сервер выполнять полное сканирование таблицы (Table Scan), игнорируя индексы.CAST в условиях WHERE препятствует использованию индексов по полям дат.Рассмотрим, как правильно переписать запрос. Вместо перечисления таблиц через запятую используем явное соединение INNER JOIN. Это позволяет оптимизатору SQL Server сразу ограничить выборку нужными связями.
SELECT
pLogData.TimeVal,
pLogData.HozOrgan,
pList.Name + ' ' + pList.FirstName + ' ' + pList.MidName AS ФИО,
pLogData.Remark
FROM pLogData
INNER JOIN pList ON pList.ID = pLogData.HozOrgan
WHERE pLogData.TimeVal >= '2022-08-03'
AND pLogData.Remark IN ('Вход, Считыватель 1', 'Выход, Считыватель 2')
Если запрос все равно выполняется долго, обязательно проверьте наличие индексов на полях, которые участвуют в связях (pList.ID, pLogData.HozOrgan) и в фильтрации (TimeVal).
Если после оптимизации запроса проблема сохраняется (например, при крайне медленных HDD-накопителях), мы можем временно увеличить таймауты подключения. Однако помните, что это «лечение симптомов», а не причины.
Соединение = Новый COMОбъект("ADODB.Connection");
Соединение.ConnectionTimeout = 300; // Увеличиваем время ожидания соединения
Соединение.CommandTimeout = 1800; // Увеличиваем время ожидания выполнения команды до 30 минут
После того как данные успешно получены из SQL, встает задача синхронизации с кадровым учетом 1С. Рассмотрим наиболее чистый архитектурный подход:
ID) для хранения ссылки на ФизЛицо из 1С. В идеале, храните там GUID или Код сотрудника из справочника 1С.ТаблицаЗначений.СостоянияСотрудников по списку всех сотрудников, полученных из SQL.ТаблицаЗначений и передайте её в СистемаКомпоновкиДанных как «Набор данных - объект». Это позволит гибко настраивать отчет без написания сложного кода вывода.Если вы планируете масштабировать решение, рекомендуем рассмотреть альтернативы прямому COM-подключению:
JSON является наиболее надежным и современным решением.Важный совет: Постарайтесь минимизировать количество операций LIKE в запросах. Если нужно выбирать данные по считывателям, лучше использовать IN или коды (идентификаторы) считывателей, если структура базы СКУД это позволяет. Это кратно повысит скорость отклика системы.