При оптимизации производительности и подготовке к техническим собеседованиям программисты 1С часто сталкиваются с вопросом: сколько реальных SQL-запросов уходит на сервер СУБД при выполнении вроде бы простого запроса к платформе. Рассмотрим классическую задачу и подробно проанализируем, как платформа «1С:Предприятие» взаимодействует с базой данных на уровне SQL Profiler.
Рассмотрим следующий фрагмент кода 1С:
Запрос = Новый Запрос;
Запрос.Текст = "
ВЫБРАТЬ ПЕРВЫЕ 1
СкидочныеКарты.Ссылка
ИЗ
Справочник.СкидочныеКарты КАК СкидочныеКарты
ГДЕ
СкидочныеКарты.КодКарты = &КодКарты";
Запрос.УстановитьПараметр("КодКарты", "КакойТоТамКодСтрокой");
На первый взгляд кажется, что здесь выполняется ровно 1 SQL-запрос. Однако если запустить трассировщик СУБД (например, MS SQL Server Profiler), результат может сильно урезать ожидание. Выясним причину такого поведения и разберем все сценарии по шагам.
Проанализируем приведенный код предельно внимательно. В представленном фрагменте присутствуют только создание объекта Запрос, установка текста и передача параметра Запрос.УстановитьПараметр.
В архитектуре 1С создание запроса и передача параметров происходят исключительно в оперативной памяти сервера приложений. Никаких вызовов к серверу базы данных в этот момент не происходит. Обращение к СУБД отправляется только тогда, когда вызывается метод Запрос.Выполнить() или Запрос.ВыполнитьПакет().
Итог: Если код исполняется строго в том виде, как написано (без вызова Выполнить()), то количество обращений к базе данных будет равно 0.
Посмотрим на ситуацию, когда метод Запрос.Выполнить() вызван, но в секции ВЫБРАТЬ указывается примитивный реквизит (например, строковый код или наименование), а не ссылка:
ВЫБРАТЬ ПЕРВЫЕ 1
СкидочныеКарты.КодКарты КАК КодКарты
ИЗ
Справочник.СкидочныеКарты КАК СкидочныеКарты
ГДЕ
СкидочныеКарты.КодКарты = &КодКарты
В этом случае платформа 1С транслирует текст в один-единственный вызов хранимой процедуры sp_executesql:
exec sp_executesql N'SELECT TOP 1
T1._Fld11
FROM dbo._Reference10 T1
WHERE (T1._Fld11 = P1)',N'P1 nvarchar(4000)',N'КакойТоТамКодСтрокой'
СУБД возвращает только запрошенную колонку, платформе не требуется подгружать дополнительную информацию об объекте. В трассировщике мы зафиксируем ровно 1 запрос.
Теперь разберем основной случай, когда в запросе выбирается поле СкидочныеКарты.Ссылка. При выборе ссылки платформа 1С включает механизм объектного кэширования сеанса.
Если объект еще не находится в кэше сеанса, при выполнении запроса и считывании результатов платформа выполняет следующие шаги:
_IDRRef из таблицы справочника:
exec sp_executesql N'SELECT TOP 1
T1._IDRRef
FROM dbo._Reference10 T1
WHERE (T1._Fld11 = P1)',N'P1 nvarchar(4000)',N'КакойТоТамКодСтрокой'
_Version:
exec sp_executesql N'SELECT
T1._Version
FROM dbo._Reference10 T1
WHERE T1._IDRRef = P1',N'P1 varbinary(16)',0x8488AC220BDA918F11E82FF8E1A9F1C6
exec sp_executesql N'SELECT
T2._IDRRef,
T2._Version,
T2._Marked,
T2._PredefinedID,
T2._Code,
T2._Description,
T2._Fld11
FROM dbo._Reference10 T2
WHERE T2._IDRRef = P1 AND T2._Version <> @P2',N'P1 varbinary(16),@P2 varbinary(8000)',0x8488AC220BDA918F11E82FF8E1A9F1C6,0x00000000000007D1
Таким образом, при первичном обращении к объекту выборка поля Ссылка генерирует в профайлере от 2 до 3 запросов к СУБД. Если тот же объект выбирается повторно и уже присутствует в кэше сеанса, количество запросов снижается до 1.
На количество запросов в профайлере также оказывают влияние дополнительные факторы:
1. Механизм RLS (Row Level Security): Если для объекта метаданных или роли текущего пользователя настроено ограничение доступа на уровне записей, платформа может предварять основной запрос служебными обращениями для выборки ключей доступа и формирования временных таблиц прав.
2. Транзакционный кэш: При исполнении кода внутри явной транзакции (между вызовами НачатьТранзакцию() и ЗафиксироватьТранзакцию()) или в обработчиках событий записи/проведения платформа использует транзакционный кэш, что предотвращает повторные служебные проверки версий данных.
Для повышения производительности высоконагруженных систем придерживайтесь простых правил:
СкидочныеКарты.Процент), избегая выборки поля Ссылка.