|
Помогите оптимизировать запрос | ☑ | ||
---|---|---|---|---|
0
JustGuest
25.03.17
✎
12:49
|
Добрый день =)
В целом запрос работает быстро и не напрягает, но головой понимаю что это сделано через одно место. Суть запроса, выбрать из Регистра Св цены номенклатуры в 1 СТРОКУ Так как цен у нас много, но в условии мы ставим их 2, то при обычном запросе будет 2 строчки, для одной цены и для другой. Через ВЫБОР не получается, та же фигня. пришлось сделать через ВТ, сначал одна цена, потом друга, а потом уже берем справочник и по нему идем. все это в последнюю ВТ и уже работаем с ним. Сам запрос ВЫБРАТЬ ЦеныНоменклатурыСрезПоследних.Цена, ЦеныНоменклатурыСрезПоследних.Валюта.код Как Валюта, ЦеныНоменклатурыСрезПоследних.Номенклатура ПОМЕСТИТЬ ВТ_ЦенаОптовая ИЗ РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК ЦеныНоменклатурыСрезПоследних ГДЕ ЦеныНоменклатурыСрезПоследних.ТипЦен = &ТипЦен ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ ЦеныНоменклатурыСрезПоследних.Номенклатура, ЦеныНоменклатурыСрезПоследних.Валюта.код Как Валюта, ЦеныНоменклатурыСрезПоследних.Цена ПОМЕСТИТЬ ВТ_ЦенаРозн ИЗ РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК ЦеныНоменклатурыСрезПоследних ГДЕ ЦеныНоменклатурыСрезПоследних.ТипЦен = &ТипЦенРозн ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ спрНоменклатура.Артикул, ВТ_ЦенаОптовая.Цена, ВТ_ЦенаОптовая.Валюта, ВТ_ЦенаРозн.Цена КАК Цена1, ВТ_ЦенаРозн.Валюта КАК Валюта1 ПОМЕСТИТЬ ВТ_Итоговая ИЗ Справочник.Номенклатура КАК спрНоменклатура ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_ЦенаОптовая КАК ВТ_ЦенаОптовая ПО спрНоменклатура.Ссылка = ВТ_ЦенаОптовая.Номенклатура ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_ЦенаРозн КАК ВТ_ЦенаРозн ПО спрНоменклатура.Ссылка = ВТ_ЦенаРозн.Номенклатура ГДЕ спрНоменклатура.ЭтоГруппа = ЛОЖЬ И спрНоменклатура.МЮС_АктивныйТовар = ИСТИНА И спрНоменклатура.ГДА_Доступность = &ГДА_Доступность ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ ВТ_Итоговая.Артикул, ВТ_Итоговая.Цена КАК ЦенаОпт, ВТ_Итоговая.Валюта КАК ВалютаОпт, ВТ_Итоговая.Цена1 КАК ЦенаРозница, ВТ_Итоговая.Валюта1 КАК ВалютаРозница ИЗ ВТ_Итоговая КАК ВТ_Итоговая |
|||
1
JustGuest
25.03.17
✎
12:50
|
За кривое форматирование сорри, первое сообщение на форуме, не знаю как сделать, чтоб код целиком был в блоке
|
|||
2
Джинн
25.03.17
✎
12:51
|
(0) На фига цены в одну строку? В чем смысл?
|
|||
3
JustGuest
25.03.17
✎
12:52
|
Отработка кода, для 6000 строк идет за 2 секунды. В целом не много, но на будущее хотел бы понять, как работать с такими запросакми
|
|||
4
JustGuest
25.03.17
✎
12:52
|
(2) Свои цели.
Далее этио все в csv и на выгрузку. |
|||
5
Sserj
25.03.17
✎
13:02
|
Или я чего то не понимаю или зачем тебе виртуальные таблицы?
ВЫБРАТЬ ВЫБРАТЬ ЕСТЬNULL(Цены1.Номенклатура, Цены2.Номенклатура) КАК Номенклатура, Цены1.Цена КАК Цена1, Цены1.Валюта.код КАК Валюта1, Цены1.Цена КАК Цена КАК Цена2, Цены1.Валюта.код КАК Валюта2 ИЗ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(,ТипЦен = &ТипЦен) КАК Цены1 ПОЛНОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(,ТипЦен = &ТипЦен2) КАК Цены2 |
|||
6
Sserj
25.03.17
✎
13:03
|
+(5) Там заменить:
Цены1.Цена КАК Цена КАК Цена2, Цены1.Валюта.код КАК Валюта2 на Цены2.Цена КАК Цена КАК Цена2, Цены2.Валюта.код КАК Валюта2 |
|||
7
JustGuest
25.03.17
✎
13:12
|
(5) Знал бы другой способ, не трогал бы =)
Буду пробоваь, через соединение Спасибо за совет |
|||
8
Sserj
25.03.17
✎
13:12
|
Что криво все получилось :)
Вот так ВЫБРАТЬ ЕСТЬNULL(Цены1.Номенклатура, Цены2.Номенклатура) КАК Номенклатура, Цены1.Цена КАК Цена1, Цены1.Валюта.код КАК Валюта1, Цены2.Цена КАК Цена КАК Цена2, Цены2.Валюта.код КАК Валюта2 ИЗ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(,ТипЦен = &ТипЦен) КАК Цены1 ПОЛНОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(,ТипЦен = &ТипЦен2) КАК Цены2 ПО Цены1.Номенклатура = Цены2.Номенклатура |
|||
9
JustGuest
25.03.17
✎
13:17
|
(8) Да норм =) Там было понятно что к чему.
В 2 раза быстрее вбыорка =) Спасибо =) подскажите, как код на форуме в блоке выводить ? |
|||
10
Bober
25.03.17
✎
13:22
|
(9) когда видишь полное соединение в запросе беги без оглядки от запросописцев.
|
|||
11
Sserj
25.03.17
✎
13:25
|
(10) Та ладно, что по твоему через объединить и сгруппировать будет чем то лучше в этом случае?
|
|||
12
Bober
25.03.17
✎
13:30
|
(11) да, будет лучше.
1. получаются данные из среза по двум типа цен и помещаются во временную таблицу 2. получаются данные из временной таблицы, объединить все. |
|||
13
pavig
25.03.17
✎
13:32
|
Я бы сделал два среза в подзапросе через ОБЪЕДИНИТЬ ВСЁ и сгруппировал
|
|||
14
pavig
25.03.17
✎
13:32
|
всё остальное - экономия на спичках и вообще от лукавого
|
|||
15
CHerypga
25.03.17
✎
13:38
|
Срез последних по обоим типам цен, выбираем только номенклатуру и в ВТ её
К получившейся ВТ левым соединением два среза последних по каждому типу цен (10) и не будет полного соединения, только вот будет ли от этого легче |
|||
16
JustGuest
25.03.17
✎
13:49
|
(15) я так и сделал. 2 среза, справочник , потом внутренним.
|
|||
17
Sserj
25.03.17
✎
16:58
|
(10)(12) Готов великодушно принять извинения :)
Не поленился сделал чистую конфигурацию: 2 справочника "Номенклатура" и "ТипыЦен". Регистр сведений "ЦеныНоменклатуры", 2 измерения "Номенклатура" и "ТипЦены" один ресурс "Цена". 1С 8.3 (8.3.10.1981) Microsoft SQL Server Standard (64-bit) 13.0.1728.2 Тестовые данные - 2 типа цен, 10000 элементов номенклатуры, в регистре "ЦеныНоменклатуры" для каждого элемента номенклатуры записи по обоим типам цен с начало года до текущей даты. Выполняю запросы обоих типов 100 раз, для получения средней скорости. Запрос объединением: 0,68406 Запрос группировкой: 0,69729 Может конечно где ошибся в самих запроса? Вот тексты: &НаКлиенте Процедура ТестЗапросов(Команда) ЗапросОбъединением = 0; ЗапросГруппировкой = 0; Для сч = 1 по 100 Цикл РезультатЗамеров = ТестЗапросовНаСервере(ТипЦен1, ТипЦен2); ЗапросОбъединением = ЗапросОбъединением + РезультатЗамеров.ЗапросОбъединением; ЗапросГруппировкой = ЗапросГруппировкой + РезультатЗамеров.ЗапросГруппировкой; КонецЦикла; РезультатЗамеров = ТестЗапросовНаСервере(ТипЦен1, ТипЦен2); Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Запрос объединением: " + (ЗапросОбъединением / 100) + Символы.ПС + "Запрос группировкой: " + (ЗапросГруппировкой / 100); Сообщение.Сообщить(); КонецПроцедуры &НаСервереБезКонтекста Функция ТестЗапросовНаСервере(ТипЦен1, ТипЦен2) // Вставить содержимое обработчика. РезультатЗамеров = Новый Структура("ЗапросОбъединением, ЗапросГруппировкой", 0, 0); ТекстЗапроса = " |ВЫБРАТЬ | ЕСТЬNULL(Цены1.Номенклатура, Цены2.Номенклатура) КАК Номенклатура, | Цены1.Цена КАК Цена1, | Цены2.Цена КАК Цена2 |ИЗ | РегистрСведений.ЦеныНоменклатуры.СрезПоследних(,ТипЦены = &ТипЦен1) КАК Цены1 | ПОЛНОЕ СОЕДИНЕНИЕ | РегистрСведений.ЦеныНоменклатуры.СрезПоследних(,ТипЦены = &ТипЦен2) КАК Цены2 | | ПО Цены1.Номенклатура = Цены2.Номенклатура |"; Запрос = Новый Запрос(ТекстЗапроса); Запрос.УстановитьПараметр("ТипЦен1", ТипЦен1); Запрос.УстановитьПараметр("ТипЦен2", ТипЦен2); началоЗапроса = ТекущаяУниверсальнаяДатаВМиллисекундах(); Результат = Запрос.Выполнить(); конецЗапроса = ТекущаяУниверсальнаяДатаВМиллисекундах(); РезультатЗамеров.ЗапросОбъединением = (конецЗапроса - началоЗапроса) / 1000; ТекстЗапроса = " |ВЫБРАТЬ | ВсеЦены.Номенклатура КАК Номенклатура | , Максимум(ВсеЦены.Цена1) КАК Цена1 | , Максимум(ВсеЦены.Цена2) КАК Цена2 |ИЗ | (ВЫБРАТЬ | Цены1.Номенклатура КАК Номенклатура | , Цены1.Цена КАК Цена1 | , 0 КАК Цена2 | ИЗ | РегистрСведений.ЦеныНоменклатуры.СрезПоследних(,ТипЦены = &ТипЦен1) КАК Цены1 | | ОБЪЕДИНИТЬ ВСЕ | | ВЫБРАТЬ | Цены2.Номенклатура | , 0 | , Цены2.Цена | ИЗ | РегистрСведений.ЦеныНоменклатуры.СрезПоследних(,ТипЦены = &ТипЦен2) КАК Цены2 | ) КАК ВсеЦены |СГРУППИРОВАТЬ ПО | ВсеЦены.Номенклатура |"; Запрос = Новый Запрос(ТекстЗапроса); Запрос.УстановитьПараметр("ТипЦен1", ТипЦен1); Запрос.УстановитьПараметр("ТипЦен2", ТипЦен2); началоЗапроса = ТекущаяУниверсальнаяДатаВМиллисекундах(); Результат = Запрос.Выполнить(); конецЗапроса = ТекущаяУниверсальнаяДатаВМиллисекундах(); РезультатЗамеров.ЗапросГруппировкой = (конецЗапроса - началоЗапроса) / 1000; Возврат РезультатЗамеров; КонецФункции |
|||
18
JustGuest
25.03.17
✎
18:24
|
(17)
не лень же вам в субботу было таким заморачиваться =) |
|||
19
Bober
26.03.17
✎
13:00
|
(17) какой то странный тест.
- как минимум нужно очищать кеши СУБД перед каждым замером и смотреть в планы запросов. - запросы к таблицам с менее 2000 записей не интересны с точки зрения оптимизации, так как СУБД считывает данные сканированием. - второй вариант ничем не отличается от первого, так как осталось двойное считывание данных из среза последних. .............. как минимум интересно смотреть от 200к записей в таблице цен и как минимум от 10к различных карточек товаров и 10 типов цен. |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |