Друзья, добрый день! Сегодня мы поговорим с вами о таком замечательном явлении как получение данных через точку от полей составного типа в запросе. Конечно же, все мы знаем, что так делать нельзя :). Но многие не знают, а что же на самом деле происходит и почему нельзя.
Вот живой пример: поступило обращение о медленном выполнении простого действия — открытие формы выбора от 2-х секунд до 2-х минут. Когда я открыл запрос, я ожидал увидеть портянку на несколько страниц, но увидел это:
Простейший запрос, в котором нет ничего интересного на первый взгляд. Кроме этого:
Заходим в конфигуратор и смотрим, какой же тип у этого загадочного объекта:
Всё скромно :). На практике же, у данного поля составной тип из всех справочников и всех документов. Итого: 657 штук!
Так вот, в MSSQL нет такого понятия как составной тип данных. Т.е. такое поле 1С в БД состоит из 2-х полей. Собственно идентификатор ссылки и тип данных.
И когда мы хотим что-либо вытянуть из такого объекта, то системе приходится искать этот объект по всем возможным типам, что здесь и произошло.
В Profiler`е это выглядело примерно так:
Огромное количество чтений с диска, высокая загрузка ЦП и длительность выполнения этого запроса почти 3 секунды. И это на базе с демонстрационными данными.
Текст получившегося SQL запроса приводить нет смысла. Используется 657(!) левых соединений. Соответственно, ни о какой работе оптимизатора не идет и речи, т.к. СУБД считает, что придумывать оптимизацию этого ада дольше, чем просто выполнить его.
План запроса Profiler не смог отобразить.
В данной ситуации получение ссылки избыточно, т.к. само поле и есть та самая ссылка. Переписав запрос ниже мы получим следующее:
И результаты в Profiler`е:
План запроса:
Запрос выполняется мгновенно. Таким образом, старайтесь избегать получения данных через точку от полей составного типа.
Если же это невозможно, то постарайтесь ограничить количество типов в запросе.
Например, в ситуации выше нам надо было бы вытянуть поле «Организация». Но мы знаем по условию задачи, что типы возможны только «Поступление товаров и услуг» и «Реализация товаров и услуг».
Вариант через применение ключевого слова «Выразить»:
Также есть вариант через внутреннее соединение с необходимым типом:
Всем спасибо за внимание!