|
Помогите оптимизировать запрос для получения остатков и цен номенклатуры | ☑ | ||
---|---|---|---|---|
0
Boudybuilder
23.10.13
✎
23:38
|
Всем доброго вечера!
Работаю на рабочим столом менеджера по продажам. Есть поле "ДеревоНоменклатуры" ТипЗначения:СправочникСписок.Номенклатура , только группы. Оно служит для навигации. При активации строки выполняется запрос , и все элементы попадают в табличную часть , откуда я уже подбираю в заказ. Все бы хорошо , но запрос долго выполняется, особенно первое выполнение запроса. Пока не закешируется. Вопрос в том , как бы тут его оптимизировать. Или как подскажете сделать по другому. Вот запрос: ВЫБРАТЬ РАЗРЕШЕННЫЕ ВЗ_Товары.КоличествоОстаток, ВЗ_Товары.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры, Цены.ЕдиницаИзмерения, Цены.Цена * Курсы.Курс / Курсы.Кратность / КурсВалютыВзаиморасчетов.Курс * КурсВалютыВзаиморасчетов.Кратность КАК Цена, ВЗ_Товары.Номенклатура КАК Номенклатура, ВЗ_Товары.Номенклатура.ДатаСоздания КАК ДатаСоздания ИЗ (ВЫБРАТЬ ТоварыНаСкладахОстатки.КоличествоОстаток КАК КоличествоОстаток, ТоварыНаСкладахОстатки.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры, ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки( , Номенклатура.Родитель = &Родитель ИЛИ Номенклатура.Родитель.Родитель = &Родитель) КАК ТоварыНаСкладахОстатки ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ ТоварыВРозницеОстатки.КоличествоОстаток, ТоварыВРозницеОстатки.ХарактеристикаНоменклатуры, ТоварыВРозницеОстатки.Номенклатура ИЗ РегистрНакопления.ТоварыВРознице.Остатки( , Номенклатура.Родитель = &Родитель ИЛИ Номенклатура.Родитель.Родитель = &Родитель) КАК ТоварыВРозницеОстатки ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ ТоварыВНТТОстатки.КоличествоОстаток, ТоварыВНТТОстатки.ХарактеристикаНоменклатуры, ТоварыВНТТОстатки.Номенклатура ИЗ РегистрНакопления.ТоварыВНТТ.Остатки( , Номенклатура.Родитель = &Родитель ИЛИ Номенклатура.Родитель.Родитель = &Родитель) КАК ТоварыВНТТОстатки) КАК ВЗ_Товары ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ТипЦен = &ТипЦены) КАК Цены ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют.СрезПоследних(, ) КАК Курсы ПО Цены.Валюта = Курсы.Валюта ПО ВЗ_Товары.ХарактеристикаНоменклатуры = Цены.ХарактеристикаНоменклатуры И ВЗ_Товары.Номенклатура = Цены.Номенклатура, РегистрСведений.КурсыВалют.СрезПоследних(, Валюта = &Валюта) КАК КурсВалютыВзаиморасчетов УПОРЯДОЧИТЬ ПО Номенклатура, Цена |
|||
1
Boudybuilder
23.10.13
✎
23:38
|
Да , и упорядовачивание почему то игнорируется...
|
|||
2
Armando
23.10.13
✎
23:46
|
Во первых, соединение со срезом последних узкое место.
|
|||
3
Armando
23.10.13
✎
23:48
|
Номенклатура.Родитель = &Родитель ИЛИ Номенклатура.Родитель.Родитель = &Родитель
тоже не очень |
|||
4
Boudybuilder
23.10.13
✎
23:52
|
Срез последних в ВТ загонять и так соединять?
|
|||
5
Armando
23.10.13
✎
23:52
|
Срезы по курсам и ценам можно выполнить один раз при открытии формы, поместить во временную таблицу. И каждый раз брать уже оттуда
|
|||
6
Boudybuilder
23.10.13
✎
23:52
|
(3) А тут тогда как быть?
Надо же по родителю отбирать... |
|||
7
Boudybuilder
23.10.13
✎
23:53
|
(5) О! ) Думаю хорошо будет.
|
|||
8
Armando
23.10.13
✎
23:57
|
(6) у тебя (3) выполняется 3 раза. Можно отдельным пакетом выбрать номенклатуру, поместить в ВТ и в параметрах виртуальной таблицы прописывать условие по номенклатуре из этой ВТ
|
|||
9
Armando
23.10.13
✎
23:58
|
(1) воткни флаг автоупорядочивание
|
|||
10
Boudybuilder
24.10.13
✎
00:03
|
(8) Я думал что лучше сразу отбор делать в ВиртуальнойТаблице чем получать данные по всем трем запросам , и их уже отбирать.
|
|||
11
Boudybuilder
24.10.13
✎
00:06
|
(8) Ну вот...
Вынес условие , и запрос дольше выполняется |
|||
12
romansun
24.10.13
✎
00:06
|
имхо трижды Родители вот эти через стопятьсот точек в параметрах виртуальной таблицы сводят скуль с ума
отбери нужную тебе номенклатуру один раз в ВТ... как в (8) посоветовали, да. Должно помочь, ибо в остальном каких-то прям явно видимых косяков вроде нет. Ну, курсы еще, да |
|||
13
romansun
24.10.13
✎
00:08
|
(11)
)))) вынеси всё номенклатуру в ВТ и запускай запросы по одному, два остальных заремарь. Отследи какой запрос больше всего затыкается. |
|||
14
Armando
24.10.13
✎
00:09
|
(10) не, что-то типа такого должно получиться:
выбрать Ссылка поместить ВТ_Номенклатура из Справочник.Номенклатура где .... ; выбрать * из РегистрНакопления.ТоварыНаСкладах.Остатки(, Номенклатура в (выбрать Ссылка из ВТ_Номенклатура)) |
|||
15
romansun
24.10.13
✎
00:11
|
+ если есть где в условиях джоинов многотиповые поля - их надо типизировать принудительно к нужному типу обязательно
"ХарактеристикаНоменклатуры" не такое? Я просто хз, что там, да как.. |
|||
16
Armando
24.10.13
✎
00:16
|
(15) думаю в данном случае нет смысла, т.к. нет получения полей через точку.
|
|||
17
Boudybuilder
24.10.13
✎
00:25
|
(8) Это как ?
Можно пример? |
|||
18
Armando
24.10.13
✎
00:29
|
(17) см (14)
|
|||
19
ViSo76
24.10.13
✎
00:41
|
За таки запросы можно сразу расстреливать на месте без суда и следствия :)
|
|||
20
Boudybuilder
24.10.13
✎
00:45
|
|ГДЕ
| ВЗ_Товары.Номенклатура В ИЕРАРХИИ(&Родитель) Это значительно помогло. Немного изменилась суть результата , но это не так важно... |
|||
21
Boudybuilder
24.10.13
✎
00:45
|
(19) Это еще что , я новичком запросы в циклах делал )))
|
|||
22
Boudybuilder
24.10.13
✎
00:46
|
(19) Стреляй! Не промахнешься... )))
|
|||
23
Armando
24.10.13
✎
00:47
|
(19) за флуд в тематической ветке тоже
|
|||
24
ViSo76
24.10.13
✎
00:57
|
Хорошо вопрос на засыпку кто скажет как будет выполнен данный кусок запроса?
РегистрНакопления.ТоварыНаСкладах.Остатки( , Номенклатура.Родитель = &Родитель ИЛИ Номенклатура.Родитель.Родитель = &Родитель) |
|||
25
Boudybuilder
24.10.13
✎
00:58
|
(24) Серьезные люди присоединились ;)
|
|||
26
Armando
24.10.13
✎
01:11
|
(24) через 2 левых и что?
|
|||
27
ViSo76
24.10.13
✎
01:22
|
А будет вот что, в начале будут получены все ближайшие остатки + движения до последнего изменения, т.к. открытый период то и захватит к примеру приход через неделю, далее идёт не два соединения а 3 соединения с фильтрацией. Это не оптимально, было бы лучше получить остатки не для всех позиций, а только для необходимой номенклатуры, вот так ( пишу запрос в блакноте так что если будут ошибки поправьте ):
ВЫБРАТЬ Ссылка КАК Номенклатура, Родитель ПОМЕСТИТЬ тзВсяНоменклатура ИЗ Справочник.Номенклатура ГДЕ Ссылка В ИЕРАРХИИ( &Родитель ) ; ВЫБРАТЬ Ссылка ПОМЕСТИТЬ тзСписокНоменклатурыДляФильтрации ИЗ тзВсяНоменклатура ГДЕ Родитель = &Родитель ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ тзВсяНоменклатура.Ссылка ИЗ тзВсяНоменклатура СОЕДИНЕНИЕ Справочник.Номенклатура КАК спрНоменклатура ПО спрНоменклатура.Ссылка = тзВсяНоменклатура.Родитель И спрНоменклатура.Родитель = &Родитель // Сделал явное соединение чтобы разжевать неявное соединение закоментированное ниже //ГДЕ // Родитель.Родитель = &Родитель ; УНИЧТОЖИТЬ тзВсяНоменклатура; ВЫБРАТЬ Номенклатура, ХарактеристикаНоменклатуры, СУММА( КоличествоОстаток ) КАК КоличествоОстаток //ПОМЕСТИТЬ тзОстатки ИЗ ( ВЫБРАТЬ Номенклатура, ХарактеристикаНоменклатуры, КоличествоОстаток ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки( , Номенклатура В ( ВЫБРАТЬ Ссылка ИЗ тзСписокНоменклатурыДляФильтрации ) ) ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ Номенклатура, ХарактеристикаНоменклатуры, КоличествоОстаток ИЗ РегистрНакопления.ТоварыВРознице.Остатки( , Номенклатура В ( ВЫБРАТЬ Ссылка ИЗ тзСписокНоменклатурыДляФильтрации ) ) ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ Номенклатура, ХарактеристикаНоменклатуры, КоличествоОстаток ИЗ РегистрНакопления.ТоварыВНТТ.Остатки( , Номенклатура В ( ВЫБРАТЬ Ссылка ИЗ тзСписокНоменклатурыДляФильтрации ) ) ) КАК втОстатки СГРУППИРОВАТЬ ПО Номенклатура, ХарактеристикаНоменклатуры ; Далее естественно срез последних так же идёт для всех номенклатур что тоже не является оптимальным... Вопрос на засыпку что нужно сделать далее? |
|||
28
Boudybuilder
24.10.13
✎
01:40
|
(27) Проверил свой запрос в УКЗ на скорость и твой...
Разницы никакой!!!! |
|||
29
Armando
24.10.13
✎
01:42
|
(27) >> А будет вот что, в начале будут получены все ближайшие остатки + движения до последнего изменения, т.к. открытый период то и захватит к примеру приход через неделю, далее идёт не два соединения а 3 соединения с фильтрацией
Не так. Просто будут получены остатки на какую-то большую дату, типа 3999 год. И 2 соединения с Номенклатурой. |
|||
30
viktor_vv
24.10.13
✎
02:34
|
А вот это
"и все элементы попадают в табличную часть" табличная часть - это что ? Табличное поле с источником данных таблица значений? Лучше так сделать. Оставляешь дерево групп для навигации. Вешаешь на форму табличное поле с источником СправочникСписок. При активизации строки дерева накладываешь отбор на список по Ссылка с условием ВГруппе. А остатки и цены выгребаешь в ПриВыводеСтроки() списка (простое условие по конкретной номенклатуре) или ПриПолученииДанных() (немного сложнее условие по массиву ссылок, но проще чем твои через несколько точек). |
|||
31
viktor_vv
24.10.13
✎
02:39
|
(30)+ У тебя в группе может быть десяток тысяч позиций номенклатуры, нафига тебе тащить остатки и цены по ним всем при активации группы, да еще и с таким тяжелым условием в параметрах, если на экран влезет максимум 50-100, вот по ним и тащи.
|
|||
32
Boudybuilder
24.10.13
✎
03:08
|
ВЫБРАТЬ РАЗРЕШЕННЫЕ
Номенклатура.Ссылка ПОМЕСТИТЬ ВТ_ВГруппе ИЗ Справочник.Номенклатура КАК Номенклатура ГДЕ Номенклатура.Родитель В ИЕРАРХИИ(&Родитель) ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ РАЗРЕШЕННЫЕ ТоварыНаСкладахОстатки.КоличествоОстаток КАК КоличествоОстаток, ТоварыНаСкладахОстатки.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры, ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура ПОМЕСТИТЬ ВТ_Остатки ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки( , Номенклатура В (ВЫБРАТЬ ВТ_ВГруппе.Ссылка ИЗ ВТ_ВГруппе)) КАК ТоварыНаСкладахОстатки ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ ТоварыВРозницеОстатки.КоличествоОстаток, ТоварыВРозницеОстатки.ХарактеристикаНоменклатуры, ТоварыВРозницеОстатки.Номенклатура ИЗ РегистрНакопления.ТоварыВРознице.Остатки( , Номенклатура В (ВЫБРАТЬ ВТ_ВГруппе.Ссылка ИЗ ВТ_ВГруппе)) КАК ТоварыВРозницеОстатки ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ ТоварыВНТТОстатки.КоличествоОстаток, ТоварыВНТТОстатки.ХарактеристикаНоменклатуры, ТоварыВНТТОстатки.Номенклатура ИЗ РегистрНакопления.ТоварыВНТТ.Остатки( , Номенклатура В (ВЫБРАТЬ ВТ_ВГруппе.Ссылка ИЗ ВТ_ВГруппе)) КАК ТоварыВНТТОстатки ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ РАЗРЕШЕННЫЕ ЦеныНоменклатурыСрезПоследних.Номенклатура, ЦеныНоменклатурыСрезПоследних.ХарактеристикаНоменклатуры, ЦеныНоменклатурыСрезПоследних.Валюта, ЦеныНоменклатурыСрезПоследних.Цена, ЦеныНоменклатурыСрезПоследних.ЕдиницаИзмерения ПОМЕСТИТЬ ВТ_ОстаткиИЦены ИЗ РегистрСведений.ЦеныНоменклатуры.СрезПоследних( , Номенклатура В (ВЫБРАТЬ ВТ_Остатки.Номенклатура ИЗ ВТ_Остатки) И ТипЦен = &ТипЦены) КАК ЦеныНоменклатурыСрезПоследних ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ ВТ_ОстаткиИЦены.Номенклатура КАК Номенклатура, ВТ_ОстаткиИЦены.ХарактеристикаНоменклатуры, ВТ_ОстаткиИЦены.ЕдиницаИзмерения, ВТ_ОстаткиИЦены.Цена * Курсы.Курс / Курсы.Кратность / КурсВалютыВзаиморасчетов.Курс * КурсВалютыВзаиморасчетов.Кратность КАК Цена, ВТ_ОстаткиИЦены.Номенклатура.ДатаСоздания КАК ДатаСоздания ИЗ ВТ_ОстаткиИЦены КАК ВТ_ОстаткиИЦены ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют.СрезПоследних КАК Курсы ПО ВТ_ОстаткиИЦены.Валюта = Курсы.Валюта, РегистрСведений.КурсыВалют.СрезПоследних(, Валюта = &Валюта) КАК КурсВалютыВзаиморасчетов УПОРЯДОЧИТЬ ПО Номенклатура, Цена АВТОУПОРЯДОЧИВАНИЕ Работает в 100 раз быстрее , + 1С не зависает при его выполнении |
|||
33
Armando
24.10.13
✎
07:48
|
Будет еще быстрее, если сделаешь (5)
Зачем здесь еще один срез, тем более без соединения: "ИЗ ВТ_ОстаткиИЦены КАК ВТ_ОстаткиИЦены ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют.СрезПоследних КАК Курсы ПО ВТ_ОстаткиИЦены.Валюта = Курсы.Валюта, РегистрСведений.КурсыВалют.СрезПоследних(, Валюта = &Валюта) КАК КурсВалютыВзаиморасчетов" Вот это тоже не понял ВТ_ОстаткиИЦены.Цена * Курсы.Курс / Курсы.Кратность / КурсВалютыВзаиморасчетов.Курс * КурсВалютыВзаиморасчетов.Кратность КАК Цена, |
|||
34
Sammo
24.10.13
✎
08:06
|
(32) Я бы таки попробовал номенклатуру убрать из параметра виртуальной таблицы и сделать внутреннее с ВТ_ВГруппе
Это скорее всего не первое измерение, размер выборки может быть большой. |
|||
35
Sammo
24.10.13
✎
08:10
|
Цены тоже не через В а через соединение.
|
|||
36
ViSo76
24.10.13
✎
08:20
|
(28) А ты проверил вместе с соединением срез последних? Конечно никакой разницы ты не почувствуешь, т.к. я только часть кода привёл. Получение цены разумеется нужно делать так:
ВЫБРАТЬ Номенклатура, ХарактеристикаНоменклатуры, Цена ИЗ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ТипЦен = &ТипЦены И ХарактеристикаНоменклатуры В ( ВЫБРАТЬ РАЗЛИЧНЫЕ Номенклатура ИЗ тзОстатки ) И ХарактеристикаНоменклатуры В ( ВЫБРАТЬ ХарактеристикаНоменклатуры ИЗ тзОстатки ) ) А то самое тормознутое оставил и радуется что не помогло... И мой запрос будет работать быстрее по тому что изначально номенклатуры может быть меньше и после получения остатков номенклатуры может ещё стать меньше и количество цен соответственно будет вычислено меньше... PS: Остальную часть запроса я предлагал написать вам... |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |