Вход | Регистрация
 
1С:Предприятие :: 1С:Предприятие 8 общая

Составной тип, производительность

Составной тип, производительность
Я
   Tigraine
 
01.06.20 - 13:51
Всем привет!

Нужно аргументированное мнение по составному типу в запросе

Мне нужно запросом вытянуть из регистра Хозрасчетный данные по документу СчетФактураВыданный (ХозрасчетныйОборотыДтКт.Регистратор - это составное поле)
Дальше мне нужно не абы какую счет фактуру выданную, а ту что ВидСчетаФактурыВыставленного = На аванс
Ещё, чтобы у счет фактуры ДокументОснование = был тип ПоступлениеНаРасчетныйСчет
После этого нужно ещё вытащить у ДокументОснование реквизит "Договор контрагента"

Итого: у меня два составных поля:
1. Регистратор
2. ДокументОснование

Я хочу написать максимально производительный запрос, ведь известно, что просто так через точку к составным полям обращаться не следует
Есть три варианта:

=======================
1. Топорный:
=======================
ВЫБРАТЬ
    ХозрасчетныйОборотыДтКт.Регистратор КАК Регистратор,
    ХозрасчетныйОборотыДтКт.Регистратор.ДокументОснование.ДоговорКонтрагента КАК ДоговорКонтрагента, (ВАУ)
    ХозрасчетныйОборотыДтКт.СуммаОборот КАК СуммаВРублях
ИЗ
    РегистрБухгалтерии.Хозрасчетный.ОборотыДтКт(
            &НачалоПериода,
            &КонецПериодаДата,
            Регистратор,
            СчетДт = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.НДСпоАвансамИПредоплатам),
            ,
            СчетКт = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.НДС),
            ,
            ) КАК ХозрасчетныйОборотыДтКт
ГДЕ
    ХозрасчетныйОборотыДтКт.Регистратор ССЫЛКА Документ.СчетФактураВыданный
    И ВЫРАЗИТЬ(ХозрасчетныйОборотыДтКт.Регистратор КАК Документ.СчетФактураВыданный).ВидСчетаФактуры = ЗНАЧЕНИЕ(Перечисление.ВидСчетаФактурыВыставленного.НаАванс)
    И ТипЗначения(ВЫРАЗИТЬ(ХозрасчетныйОборотыДтКт.Регистратор КАК Документ.СчетФактураВыданный).ДокументОснование) = Тип(Документ.ПоступлениеНаРасчетныйСчет)


=======================
2. Ещё более или менее
=======================
ВЫБРАТЬ
    ХозрасчетныйОборотыДтКт.Регистратор КАК Регистратор,
    ХозрасчетныйОборотыДтКт.СуммаОборот КАК СуммаВРублях
ПОМЕСТИТЬ ВТ_1
ИЗ
    РегистрБухгалтерии.Хозрасчетный.ОборотыДтКт(
            &НачалоПериода,
            &КонецПериодаДата,
            Регистратор,
            СчетДт = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.НДСпоАвансамИПредоплатам),
            ,
            СчетКт = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.НДС),
            ,
            ) КАК ХозрасчетныйОборотыДтКт
ГДЕ
    ХозрасчетныйОборотыДтКт.Регистратор ССЫЛКА Документ.СчетФактураВыданный
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ_1.Регистратор КАК Регистратор,
    ВТ_1.СуммаВРублях КАК СуммаВРублях
ПОМЕСТИТЬ ВТ_2    
ИЗ
    ВТ_1 КАК ВТ_1
ГДЕ
    ВТ_1.Регистратор.ВидСчетаФактуры = ЗНАЧЕНИЕ(Перечисление.ВидСчетаФактурыВыставленного.НаАванс)
    И ТИПЗНАЧЕНИЯ(ВТ_1.Регистратор.ДокументОснование) = ТИП(Документ.ПоступлениеНаРасчетныйСчет)
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ_2.Регистратор КАК Регистратор,
    ВТ_2.Регистратор.ДокументОснование.ДоговорКонтрагента КАК ДоговорКонтрагента,
    ВТ_2.СуммаВРублях КАК СуммаВРублях
ИЗ
    ВТ_2 КАК ВТ_2

=======================
3. Мега предусмотрительный
=======================
ВЫБРАТЬ
    ХозрасчетныйОборотыДтКт.Регистратор КАК Регистратор,
    ХозрасчетныйОборотыДтКт.СуммаОборот КАК СуммаВРублях
ПОМЕСТИТЬ ВТ_1
ИЗ
    РегистрБухгалтерии.Хозрасчетный.ОборотыДтКт(
            &НачалоПериода,
            &КонецПериодаДата,
            Регистратор,
            СчетДт = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.НДСпоАвансамИПредоплатам),
            ,
            СчетКт = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.НДС),
            ,
            ) КАК ХозрасчетныйОборотыДтКт
ГДЕ
    ХозрасчетныйОборотыДтКт.Регистратор ССЫЛКА Документ.СчетФактураВыданный
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ_1.Регистратор КАК Регистратор,
    ВТ_1.СуммаВРублях КАК СуммаВРублях
ПОМЕСТИТЬ ВТ_2    
ИЗ
    ВТ_1 КАК ВТ_1
ГДЕ
    ВЫРАЗИТЬ(ВТ_1.Регистратор КАК Документ.СчетФактураВыданный).ВидСчетаФактуры = ЗНАЧЕНИЕ(Перечисление.ВидСчетаФактурыВыставленного.НаАванс)
    И ТИПЗНАЧЕНИЯ(ВЫРАЗИТЬ(ВТ_1.Регистратор КАК Документ.СчетФактураВыданный).ДокументОснование) = ТИП(Документ.ПоступлениеНаРасчетныйСчет)
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ_2.Регистратор КАК Регистратор,
    ВЫРАЗИТЬ(ВЫРАЗИТЬ(ВТ_2.Регистратор КАК Документ.СчетФактураВыданный).ДокументОснование КАК Документ.ПоступлениеНаРасчетныйСчет).ДоговорКонтрагента КАК ДоговорКонтрагента,
    ВТ_2.СуммаВРублях КАК СуммаВРублях
ИЗ
    ВТ_2 КАК ВТ_2




ВОПРОС: как всё-таки правильно работать с составными типами в запросе для максимальной производительности? И если ты уже отфильтровал регистратор по определенному типу, а потом обращается к нему через точку, то будет ли соединения с одним типом или по-прежнему с несколькими?
   RomanYS
 
1 - 01.06.20 - 13:56
явное соединение с таблицей Документ.СчетФактураВыданный.
Если тоже сильносоставное(десятки типов), то ещё и явное соединение с этой таблицей
   RomanYS
 
2 - 01.06.20 - 13:57
*(1) если поле ДокументОснование ...
   palsergeich
 
3 - 01.06.20 - 14:00
"отфильтровал регистратор по определенному типу, а потом обращается к нему через точку, то будет ли соединения с одним типом или по-прежнему с несколькими"
Если ты явно в запросе выходное поле не типизировал через ВЫРАЗИТЬ КАК то будут по-прежнему с несколькими.
Оператор Ссылка не ограничивает типы в ОРМ и он по прежднему думает что там составной тип. Явным указанием на ограничение типа является Выразить в выходном поле запроса
   fisher
 
4 - 01.06.20 - 14:00
Слоеного пирога с временными таблицами я не понял, а вникать лень.
Но отвечая на последний вопрос - без ВЫРАЗИТЬ при обращении через точку будут соединения со всеми таблицами составного типа. Независимо от того, чего там отфильтровано.
Работать просто. Фильтровать через ССЫЛКА, доступаться через ВЫРАЗИТЬ.
   Конструктор1С
 
5 - 01.06.20 - 14:01
Не используй виртуальную таблицу регистра бухгалтерии, ты можешь получить все эти данные через соединение таблицы движений с таблицей документа. Только в условиях соединения/отбор задействуй период, чтобы попасть в стандартный индекс
   Конструктор1С
 
6 - 01.06.20 - 14:39
Глянул в БП, тебе вообще повезло

Стандартные индексы регистра бухгалтерии
СчетДт + Период + Регистратор
СчетКт + Период + Регистратор

Индексы счета-фактуры
ВидСчетаФактуры + Ссылка (реквизит индексирован)
ДокументОснование + Ссылка (реквизит индексирован)
   Tigraine
 
7 - 01.06.20 - 15:39
судя по комментариям, первый вариант стоит доработать и будет вполне приемлемо?



ВЫБРАТЬ
    ХозрасчетныйОборотыДтКт.Регистратор КАК Регистратор,
    ВЫРАЗИТЬ(ВЫРАЗИТЬ(ХозрасчетныйОборотыДтКт.Регистратор КАК Документ.СчетФактураВыданный).ДокументОснование КАК Документ.ПоступлениеНаРасчетныйСчет).ДоговорКонтрагента КАК ДоговорКонтрагента,
    ХозрасчетныйОборотыДтКт.СуммаОборот КАК СуммаВРублях

ИЗ
    РегистрБухгалтерии.Хозрасчетный.ОборотыДтКт(
            &НачалоПериода,
            &КонецПериодаДата,
            Регистратор,
            СчетДт = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.НДСпоАвансамИПредоплатам),
            ,
            СчетКт = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.НДС),
            ,
            ) КАК ХозрасчетныйОборотыДтКт
ГДЕ
    ХозрасчетныйОборотыДтКт.Регистратор ССЫЛКА Документ.СчетФактураВыданный
    И ВЫРАЗИТЬ(ХозрасчетныйОборотыДтКт.Регистратор КАК Документ.СчетФактураВыданный).ВидСчетаФактуры = ЗНАЧЕНИЕ(Перечисление.ВидСчетаФактурыВыставленного.НаАванс)
    И ТипЗначения(ВЫРАЗИТЬ(ХозрасчетныйОборотыДтКт.Регистратор КАК Документ.СчетФактураВыданный).ДокументОснование) = Тип(Документ.ПоступлениеНаРасчетныйСчет)
   Tigraine
 
8 - 01.06.20 - 16:06
(4) fisher, т.е. даже если создать временную таблицу куда поместить только СчетФактураВыданный, а затем обратится уже ко временной таблице к Регистратор через точку, то всё равно будет соединяться со всеми типами составного поля? Это точно?
   palsergeich
 
9 - 01.06.20 - 16:09
(8) Если в пакете ранее Регистратору не сделал Выразить - то точно.
Это стандартная ошибка новичков.
   palsergeich
 
10 - 01.06.20 - 16:10
(8) Эту штуку тоже надо через Выразить прогнать "ХозрасчетныйОборотыДтКт.Регистратор КАК Регистратор"
Если тип один то тупо выразить, если немного то через Выбор когда тогда
Если нужны типы все то нужно придумывать пути обхода
   fisher
 
11 - 01.06.20 - 16:17
(8) Скажу так: уверен, что будет именно так, но с профайлером не проверял. Чтобы произошло иначе, платформа на этапе конвертации запроса должна по распарсенному условию догадаться, что содержимое временной таблицы будет однозначно типизировано и учесть это при конвертации конструкции обращения через точку от регистратора. Уверен, что настолько хитро-глубоких семантических оптимизаций в платформе нет.
   palsergeich
 
12 - 01.06.20 - 16:20
(11) А я лазил, когда простейший запрос выполнялся 15 секунд, думал что ссылка в условии спасает, но это не так)
Давно это было.
Действительно движок генератора SQL запросов в плане генерации к полям составных типов очень примитивен, и надо руками)

Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.