Имя: Пароль:
1C
1С v8
работа с вложенным запросом как с параметром вирт таблицы
,
0 lisrws
 
16.01.13
15:03
Платформа 1С:Предприятие 8.2 (8.2.15.318)
есть запрос:
ВЫБРАТЬ
ТоварыВНТТОстатки.Номенклатура
ИЗ
РегистрНакопления.ТоварыВНТТ.Остатки(,Склад = &Склад
И (Номенклатура, ХарактеристикаНоменклатуры) В
        (ВЫБРАТЬ
        А.Номенклатура,
        А.ХарактеристикаНоменклатуры
        ИЗ
        РегистрСведений.РеферентныеЦены.СрезПоследних(, ) КАК А
        ГДЕ
        А.АктивностьРефЦены)) КАК ТоварыВНТТОстатки
СГРУППИРОВАТЬ ПО
   ТоварыВНТТОстатки.Номенклатура

в параметрах таблицы ТоварыВНТТОстатки указываются критерии для полей (Номенклатура, ХарактеристикаНоменклатуры) в виде результата выполнения запроса по рс Реф цены. записей в этом рс немного(30-40), остатков в нтт больше, чем по 3000 позиций. логично, что не нужно получать остатки по всем записям из ТоварыВНТТ, если нам нужны только остатки по позициям из РеферентныеЦены, поэтому используем отбор вирт таблицы. и тут начинается самое интересное. если мы выполняем запрос как написано выше, он выполняется дольше в 2-3 раза, чем если бы без кода "(Номенклатура, ХарактеристикаНоменклатуры) В
        (ВЫБРАТЬ
        А.Номенклатура,
        А.ХарактеристикаНоменклатуры
        ИЗ
        РегистрСведений.РеферентныеЦены.СрезПоследних(, ) КАК А
        ГДЕ
        А.АктивностьРефЦены)"
То есть получение остатков по отбору на 30 позиций выполняется в 3 раза дольше, чем получение остатков без отбора по 3000 позиций.
Но если мы этот вложенный запрос изменим, оставив в нем только: "Номенклатура В
        (ВЫБРАТЬ
        А.Номенклатура
        ИЗ
        РегистрСведений.РеферентныеЦены.Срез...."
то выполняется моментально, собственно как и ожидалось.
ХарактеристикаНоменклатуры везде не заполнена, то есть вообще не используется по факту.
АктивностьРефЦены - везде истина.

кто-нибудь может просветить меня в тонкостях такого рода работы с параметрами вирт таблицы?
1 ProgAL
 
16.01.13
15:10
Проиндексиркй поля ВТ.
2 ProgAL
 
16.01.13
15:12
Сорри ошибся. Замени свой запрос на внутренее соединение.
3 Fragster
 
гуру
16.01.13
15:14
(Склад, Номенклатура, ХарактеристикаНоменклатуры) В
        (ВЫБРАТЬ
&Склад,
        А.Номенклатура,
        А.ХарактеристикаНоменклатуры
        ИЗ
        РегистрСведений.РеферентныеЦены.СрезПоследних(, ) КАК А
        ГДЕ
        А.АктивностьРефЦены)
4 Fragster
 
гуру
16.01.13
15:14
если в регистре ТоварыВНТТОстатки измерения идут в таком порядке :)
5 fisher
 
16.01.13
15:16
Я практически уверен, что дело в операторе В.
"В" на единичное вхождение напрямую транслируется в стандартный IN. А вариант "(,) В (,)" сильно подозреваю, что транслируется в что-то шибко жуткое в твоем случае.
Ибо синтаксис "(,) IN (,)" СУБД не поддерживается.
6 Fragster
 
гуру
16.01.13
15:31
(5) судя по профайлеру - сначала помещается во временную таблицу, потом юзается exists
7 lisrws
 
16.01.13
15:43
Внутреннее соединение поможет отфильтровать конечный результат, но остатки всё равно будут получены по 3000 позициям, вместо 30.

внес в запрос склад. не помогло.

"Я практически уверен, что дело в операторе В" - я тоже к этому склоняюсь, но интересно как на самом деле. а никакой аналогичной инструкции нет для неединчных вхождений?

через вт гораздо быстрей стало работать. потом добавил индексацию в эту вт и вообще лётать стало. жаль что с вложенным запросом так не получается делать.
спасибо всем
8 Fragster
 
гуру
16.01.13
15:55
вот на такой запрос:


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


говорит, что ищет по кластерному индексу период-склад-номенклатура
9 cw014
 
16.01.13
16:00
ВЫБРАТЬ
        А.Номенклатура,
        А.ХарактеристикаНоменклатуры
ПОМЕСТИТЬ РеферентныеЦены
ИЗ
        РегистрСведений.РеферентныеЦены.СрезПоследних(, ) КАК А
ГДЕ
        А.АктивностьРефЦены
;

ВЫБРАТЬ
        ТоварыВНТТОстатки.Номенклатура
ИЗ
        РегистрНакопления.ТоварыВНТТ.Остатки(,Склад = &Склад
                 И Номенклатура В (ВЫБРАТЬ РАЗЛИЧНЫЕ Номенклатура ИЗ РеферентныеЦены КАК РеферентныеЦены)
                 И  ХарактеристикаНоменклатуры В (ВЫБРАТЬ РАЗЛИЧНЫЕ ХарактеристикаНоменклатуры ИЗ РеферентныеЦены КАК РеферентныеЦены)) КАК ТоварыВНТТОстатки
СГРУППИРОВАТЬ ПО
   ТоварыВНТТОстатки.Номенклатура
10 cw014
 
16.01.13
16:00
А ну и в конце добавь:

УНИЧТОЖИТЬ РеферентныеЦены
11 Fragster
 
гуру
16.01.13
16:01
(9) только надо еще внутреннее соединение сделать ТоварыВНТТОстатки с РеферентныеЦены
12 Fragster
 
гуру
16.01.13
16:01
(7) а как именно измерения в таблице идут?
13 Fragster
 
гуру
16.01.13
16:01
в регистре
14 cw014
 
16.01.13
16:02
(11) Неа, не нужно
15 Fragster
 
гуру
16.01.13
16:05
(14) да, нужно. допустим, на остатках есть товар1 с характеристикой1 и характеристикой2, и товар2 с характеристикой1 и характеристикой2. а в референтных ценах у товар2 только с характеристикой1. тогда твой запрос выведет лишнюю информацию.
16 fisher
 
16.01.13
16:05
(9) Два "В" не идентичны "В" по комбинации двух полей.
17 lisrws
 
16.01.13
16:13
(12)
Склад,
ТоварТара,
Номенклатура,
ХарактеристикаНоменклатуры
18 Fragster
 
гуру
16.01.13
16:13
(17) тогда тебе нужен ТоварТара еще в запросе
19 Fragster
 
гуру
16.01.13
16:13
(18)+ или поменяй его с номенклатурой местами
20 lisrws
 
16.01.13
16:13
(6)
а профайлер - это что?
21 Fragster
 
гуру
16.01.13
16:14
(20) профайлер - это когда v8: Насколько востребованы такие знания? будешь озабочиваться - очень поможет
22 Fragster
 
гуру
16.01.13
16:15
(19) вернее под номенклатуру и характеристику
23 fisher
 
16.01.13
16:35
(20) В этом контексте - инструмент MSSQL, позволяющий мониторить запросы к базе данных. В данном случае - запросы, которые шлет сервер приложений.
24 lisrws
 
16.01.13
16:43
(22)
сделал так:
"ВЫБРАТЬ
ТоварыВНТТОстатки.Номенклатура,
СУММА(ТоварыВНТТОстатки.КоличествоОстаток) КАК Остаток
ИЗ
РегистрНакопления.ТоварыВНТТ.Остатки(
,
(Склад, ТоварТара, Номенклатура, ХарактеристикаНоменклатуры) В
   (ВЫБРАТЬ
   &Склад КАК Склад,
   Значение(Перечисление.ТоварТара.Товар) КАК ТоварТара,
   А.Номенклатура,
   А.ХарактеристикаНоменклатуры
   ИЗ
   РегистрСведений.РеферентныеЦены.СрезПоследних(, ) КАК А
   ГДЕ
   А.АктивностьРефЦены)) КАК ТоварыВНТТОстатки
СГРУППИРОВАТЬ ПО
ТоварыВНТТОстатки.Номенклатура";

не помогло. оставил через вт.

(21) спасибо
25 ProgAL
 
16.01.13
16:50
Можно убрать проверку вхождения по номенклатуре, а оставить только характеристику, которая однозначно относится к номенклатуре.
26 lisrws
 
16.01.13
16:57
(25)
она не однозначно относится. в (15) описана ситуация. и здесь вся замануха в том, как отобрать через В за раз по несколько записей
27 Fragster
 
гуру
16.01.13
18:15
(24) вынеси весь вложенный запрос в ВТ, и в В оставь все поля
28 lisrws
 
16.01.13
18:59
(27) так делал. работает как и нужно, но хотелось именно через влож запрос. как говорится: душа просит))))
29 Fragster
 
гуру
16.01.13
19:24
(28) при больших вложенных запросах (а виртуальные таблицы именно такими и являются) оптимизатор запросов сходит с ума и действует неоптимально. 1с не рекомендует соединять и вкладывать запросы к виртуальным таблицам.

Когда запросы тупят - надо смотреть профайлер.
30 Fragster
 
гуру
16.01.13
19:28
он говорит, на каком куске тормозит больше всего. например в (8) больше всего тормозит сортировка результатов вложенного запроса (вероятно чтобы накладывать на кластерный индекс)
31 lisrws
 
17.01.13
11:47
(30)
спасибо за полезную инфу. надо будет скачать сей профайлер и поиграться)))