Часто разработчики сталкиваются с ситуацией: прямой SELECT к таблице базы данных через SQL Server Management Studio выполняется мгновенно, а аналогичный запрос в консоли 1С занимает ощутимое время. Давайте разберем, почему это происходит и как оптимизировать работу с большими объемами данных.
Запрос, написанный на встроенном языке 1С, не является прямым SQL-кодом. Платформа выполняет промежуточные действия, которые требуют ресурсов:
Первым делом проанализируем состояние сервера. Если сервер приложений 1С и SQL Server установлены на одной машине, они начинают бороться за ресурсы. Самая частая проблема — отсутствие ограничений на использование оперативной памяти для SQL Server. Если SQL Server не ограничен, он занимает всю доступную память, что заставляет операционную систему использовать файл подкачки, замедляя все процессы.
Что сделать:
RAID массиве, очередь диска может стать «бутылочным горлышком».При работе с большими выборками старайтесь минимизировать передачу данных между сервером 1С и SQL. Использование временных таблиц в 1С позволяет выполнить тяжелую операцию на стороне СУБД и удержать результат там до конца транзакции.
Рассмотрим пример кода, который позволяет работать эффективнее:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка
|ПОМЕСТИТЬ ВТ_Номенклатура
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|;
|ВЫБРАТЬ
| ВТ.Ссылка
|ИЗ
| ВТ_Номенклатура КАК ВТ";
Результат = Запрос.Выполнить();
Такой подход помогает исключить избыточную нагрузку при получении больших выборок, так как данные не будут целиком выгружаться в память клиента (или сервера приложений) до завершения всех необходимых манипуляций.
Если запрос все еще работает медленно, необходимо увидеть, что именно отправляет платформа 1С в СУБД. Гадать не нужно — используйте инструменты профилирования:
DBMSSQL. Это позволит увидеть реальный текст SQL-запроса, который исполняется, а также длительность его выполнения. Часто там можно обнаружить неожиданные JOIN-ы или проверки, которые замедляют работу.Index Seek вы видите Table Scan, значит, система вынуждена читать всю таблицу целиком, что критично при 60 000+ записей.Многие разработчики совершают ошибку, обращаясь к Представление в цикле. Если в запросе 1С вы обращаетесь к Н.Ссылка, а затем в цикле 1С вызываете представление для каждого элемента, платформа выполняет N запросов к базе данных (проблема N+1). Чтобы ускорить работу, всегда выбирайте необходимые поля сразу в одном запросе:
// Правильный подход
Запрос.Текст =
"ВЫБРАТЬ
| Н.Ссылка,
| Н.Наименование КАК Представление
|ИЗ
| Справочник.Номенклатура КАК Н";
Таким образом, мы разгружаем систему, заставляя SQL выполнить один эффективный запрос вместо множества обращений.
Помните: оптимизация — это всегда поиск баланса между железом и качеством написанного кода. Начните с ограничения памяти SQL-сервера, затем переходите к профилированию через ТЖ и используйте ПОМЕСТИТЬ для промежуточных выборок.