|
Оптимизация запроса или что-то еще? | ☑ | ||
---|---|---|---|---|
0
noxxx
13.11.13
✎
10:44
|
Господа, есть запрос, выполняющийся 4 секунды. Выполняется он в модуле проведения заказа покупателя, я уже писал об этом.
При высокой активности пользователей запрос может выполняться дольше, пользователи встают в очередь, возникают взаимные блокировки, крики, вопли. Запрос проверяет какое количество продукции по моделям и товарным группам мы уже приняли с определенной датой выпуска, и если ограничения позволяют, то принимаем еще. Если нет - не принимаем. Есть вариант перенести эту проверку в процедуру ПередЗаписьюНаСервере и проверять там, но т.к. это дело будет выполняться вне транзакции, то есть вероятность что лимиты производства будут превышены, чего не хотелось бы. Может быть кто-нибудь посоветует как переделать запрос таким образом, чтобы SQL строила более оптимальный план запроса, например, и он выполнялся бы быстрее? Сам запрос: ВЫБРАТЬ СУММА(ЗаказыПокупателейОстаткиСвернуто.КоличествоОстаток - ЕСТЬNULL(ЗаказыПоставщикамОстатки.КоличествоОстаток, 0) - ЕСТЬNULL(ТоварыВРезервеНаСкладах.КоличествоОстаток, 0)) КАК Количество, ЗначенияСвойствОбъектовТоварнаяГруппа.Значение КАК ТоварнаяГруппа, ЗначенияСвойствОбъектовМодель.Значение КАК Модель ИЗ (ВЫБРАТЬ ЗаказыПокупателейОстатки.Номенклатура КАК Номенклатура, ЗаказыПокупателейОстатки.ЗаказПокупателя КАК ЗаказПокупателя, СУММА(ЕСТЬNULL(ЗаказыПокупателейОстатки.КоличествоОстаток, 0)) КАК КоличествоОстаток ИЗ РегистрНакопления.ЗаказыПокупателей.Остатки( &ДатаОстатков, СтатусПартии <> ЗНАЧЕНИЕ(Перечисление.СтатусыПартийТоваров.ВозвратнаяТара) И НЕ Номенклатура.Комплект И НЕ Номенклатура.Услуга И Номенклатура.ВидВоспроизводства = &ВидВоспроизводства И ЗаказПокупателя <> &Заказ И ЗаказПокупателя.оДатаВыпуска = &ДатаОграничения) КАК ЗаказыПокупателейОстатки СГРУППИРОВАТЬ ПО ЗаказыПокупателейОстатки.ЗаказПокупателя, ЗаказыПокупателейОстатки.Номенклатура) КАК ЗаказыПокупателейОстаткиСвернуто ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.РазмещениеЗаказовПокупателей.Остатки( &ДатаОстатков, ТоварТара = ЗНАЧЕНИЕ(Перечисление.ТоварТара.Товар) И ТИПЗНАЧЕНИЯ(ЗаказПоставщику) = ТИП(Документ.ЗаказПоставщику) И ЗаказПокупателя <> &Заказ) КАК ЗаказыПоставщикамОстатки ПО ЗаказыПокупателейОстаткиСвернуто.Номенклатура = ЗаказыПоставщикамОстатки.Номенклатура И ЗаказыПокупателейОстаткиСвернуто.ЗаказПокупателя = ЗаказыПоставщикамОстатки.ЗаказПокупателя ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки(&ДатаОстатков, ДокументРезерва <> &Заказ) КАК ТоварыВРезервеНаСкладах ПО ЗаказыПокупателейОстаткиСвернуто.Номенклатура = ТоварыВРезервеНаСкладах.Номенклатура И ЗаказыПокупателейОстаткиСвернуто.ЗаказПокупателя = ТоварыВРезервеНаСкладах.ДокументРезерва ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектовТоварнаяГруппа ПО ЗаказыПокупателейОстаткиСвернуто.Номенклатура = ЗначенияСвойствОбъектовТоварнаяГруппа.Объект И (ЗначенияСвойствОбъектовТоварнаяГруппа.Свойство.Наименование = "Товарная группа") ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектовМодель ПО ЗаказыПокупателейОстаткиСвернуто.Номенклатура = ЗначенияСвойствОбъектовМодель.Объект И (ЗначенияСвойствОбъектовМодель.Свойство.Наименование = "Модель") ГДЕ ЗаказыПокупателейОстаткиСвернуто.КоличествоОстаток - ЕСТЬNULL(ЗаказыПоставщикамОстатки.КоличествоОстаток, 0) - ЕСТЬNULL(ТоварыВРезервеНаСкладах.КоличествоОстаток, 0) > 0 СГРУППИРОВАТЬ ПО ЗначенияСвойствОбъектовТоварнаяГруппа.Значение, ЗначенияСвойствОбъектовМодель.Значение |
|||
1
Ненавижу 1С
гуру
13.11.13
✎
10:47
|
избавься от:
И (ЗначенияСвойствОбъектовТоварнаяГруппа.Свойство.Наименование = "Товарная группа") И (ЗначенияСвойствОбъектовМодель.Свойство.Наименование = "Модель") |
|||
2
Нуф-Нуф
13.11.13
✎
10:47
|
ужаснах
|
|||
3
Нуф-Нуф
13.11.13
✎
10:48
|
РегистрНакопления.ЗаказыПокупателей.Остатки и РегистрНакопления.РазмещениеЗаказовПокупателей.Остатки в в отдельные временные таблицы
|
|||
4
Sabbath
13.11.13
✎
10:48
|
(0) разыменование в условиях и соединениях - не очень
ну и попробуй без вложенных |
|||
5
Нуф-Нуф
13.11.13
✎
10:48
|
РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки тоже
|
|||
6
Sabbath
13.11.13
✎
10:48
|
+(4) с ВТ
|
|||
7
Sabbath
13.11.13
✎
10:49
|
а блокировки и взаимоблокировки все равно могут быть)
|
|||
8
Ненавижу 1С
гуру
13.11.13
✎
10:50
|
может вмето ГДЕ надо ИМЕЮЩИЕ по логике?
|
|||
9
Нуф-Нуф
13.11.13
✎
10:50
|
И ЗаказПокупателя <> &Заказ
И ЗаказПокупателя.оДатаВыпуска = &ДатаОграничения можно заменить отдельной таблицей с индексацией и ее совать в параметры временной таблицы ЗаказыПокупателей.Остатки |
|||
10
Нуф-Нуф
13.11.13
✎
10:50
|
(7) блокировки и взаимоблокировки как бы разные вещи
|
|||
11
noxxx
13.11.13
✎
10:51
|
(7) Да это понятно, но когда проведение документа из-за очередей занимает до 30 секунд - это плохо.
(1) А как сделать лучше? |
|||
12
Нуф-Нуф
13.11.13
✎
10:53
|
И (ЗначенияСвойствОбъектовТоварнаяГруппа.Свойство = &СвойствоГруппа)
И (ЗначенияСвойствОбъектовМодель.Свойство = &СвойствоМодель) |
|||
13
WildSery
13.11.13
✎
10:55
|
Вложенный запрос радует.
Достаём остатки по Номенклатуре и Заказу, а потом ещё зачем-то группируем по ним же. ЕстьNULL внутри суммы тоже хорош. |
|||
14
Ненавижу 1С
гуру
13.11.13
✎
10:55
|
(11) предопределнные значения или константы
|
|||
15
noxxx
13.11.13
✎
11:03
|
(13) Потом к этой таблице присоединяются резервы и размещения, и если в заказе, например, будет 2 строки одной номенклатуры, но с разной ценой, то будет 2 строки на номенклатуру. Разве нет?
|
|||
16
WildSery
13.11.13
✎
11:19
|
(15) С какой ещё ценой? Я говорю об этом:
ВЫБРАТЬ Номенклатура, ЗаказПокупателя, СУММА(ЕСТЬNULL(КоличествоОстаток, 0)) ИЗ РегистрНакопления.ЗаказыПокупателей.Остатки() КАК ЗаказыПокупателейОстатки СГРУППИРОВАТЬ ПО ЗаказПокупателя, Номенклатура |
|||
17
noxxx
13.11.13
✎
11:47
|
(16) Я уже понял.
Переделал запрос в соответствии с рекомендациями, стало намного быстрее: ВЫБРАТЬ РАЗЛИЧНЫЕ ЗаказПокупателя.Ссылка КАК Ссылка ПОМЕСТИТЬ ЗаказыНаДатуВыпуска ИЗ Документ.ЗаказПокупателя КАК ЗаказПокупателя ГДЕ ЗаказПокупателя.оДатаВыпуска = &ДатаОграничения И ЗаказПокупателя.Проведен = ИСТИНА ИНДЕКСИРОВАТЬ ПО Ссылка ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ ЗаказыПокупателейОстатки.Номенклатура КАК Номенклатура, ЗаказыПокупателейОстатки.ЗаказПокупателя КАК ЗаказПокупателя, ЗаказыПокупателейОстатки.КоличествоОстаток КАК КоличествоОстаток ПОМЕСТИТЬ Заказы ИЗ РегистрНакопления.ЗаказыПокупателей.Остатки( &ДатаОстатков, СтатусПартии <> ЗНАЧЕНИЕ(Перечисление.СтатусыПартийТоваров.ВозвратнаяТара) И НЕ Номенклатура.Комплект И НЕ Номенклатура.Услуга И ЗаказПокупателя <> &Заказ И ЗаказПокупателя В (ВЫБРАТЬ ЗаказыНаДатуВыпуска.Ссылка ИЗ ЗаказыНаДатуВыпуска)) КАК ЗаказыПокупателейОстатки ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ РазмещениеЗаказовПокупателейОстатки.ЗаказПокупателя, РазмещениеЗаказовПокупателейОстатки.Номенклатура, РазмещениеЗаказовПокупателейОстатки.КоличествоОстаток ПОМЕСТИТЬ РазмещениеЗаказов ИЗ РегистрНакопления.РазмещениеЗаказовПокупателей.Остатки( &ДатаОстатков, НЕ Номенклатура.Комплект И НЕ Номенклатура.Услуга И ЗаказПокупателя <> &Заказ И ЗаказПокупателя В (ВЫБРАТЬ ЗаказыНаДатуВыпуска.Ссылка ИЗ ЗаказыНаДатуВыпуска)) КАК РазмещениеЗаказовПокупателейОстатки ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ ТоварыВРезервеНаСкладахОстатки.Номенклатура, ТоварыВРезервеНаСкладахОстатки.ДокументРезерва, ТоварыВРезервеНаСкладахОстатки.КоличествоОстаток ПОМЕСТИТЬ РезервыНаСкладах ИЗ РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки( &ДатаОстатков, НЕ Номенклатура.Комплект И НЕ Номенклатура.Услуга И ДокументРезерва <> &Заказ И ДокументРезерва В (ВЫБРАТЬ ЗаказыНаДатуВыпуска.Ссылка ИЗ ЗаказыНаДатуВыпуска)) КАК ТоварыВРезервеНаСкладахОстатки ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ ЗаказыНаДату.КоличествоОстаток + ЕСТЬNULL(РазмещениеЗаказов.КоличествоОстаток, 0) + ЕСТЬNULL(РезервыНаСкладах.КоличествоОстаток, 0) КАК Количество, ЕСТЬNULL(ЗначенияСвойствОбъектовТГ.Значение, ЗНАЧЕНИЕ(Справочник.оТоварныеГруппы.ПустаяСсылка)) КАК ТоварнаяГруппа, ЕСТЬNULL(ЗначенияСвойствОбъектовМодель.Значение, ЗНАЧЕНИЕ(Справочник.оМодели.ПустаяСсылка)) КАК Модель ПОМЕСТИТЬ ИТОГ ИЗ Заказы КАК ЗаказыНаДату ЛЕВОЕ СОЕДИНЕНИЕ РазмещениеЗаказов КАК РазмещениеЗаказов ПО ЗаказыНаДату.ЗаказПокупателя = РазмещениеЗаказов.ЗаказПокупателя И ЗаказыНаДату.Номенклатура = РазмещениеЗаказов.Номенклатура ЛЕВОЕ СОЕДИНЕНИЕ РезервыНаСкладах КАК РезервыНаСкладах ПО ЗаказыНаДату.ЗаказПокупателя = РезервыНаСкладах.ДокументРезерва И ЗаказыНаДату.Номенклатура = РезервыНаСкладах.Номенклатура ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектовТГ ПО ЗаказыНаДату.Номенклатура = ЗначенияСвойствОбъектовТГ.Объект И (ЗначенияСвойствОбъектовТГ.Свойство = &СвойствоТоварнаяГруппа) ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектовМодель ПО ЗаказыНаДату.Номенклатура = ЗначенияСвойствОбъектовМодель.Объект И (ЗначенияСвойствОбъектовМодель.Свойство = &СвойствоМодель) ГДЕ ЗаказыНаДату.КоличествоОстаток + ЕСТЬNULL(РазмещениеЗаказов.КоличествоОстаток, 0) + ЕСТЬNULL(РезервыНаСкладах.КоличествоОстаток, 0) > 0 ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ ИТОГ.ТоварнаяГруппа, ИТОГ.Модель, СУММА(ИТОГ.Количество) КАК Количество ИЗ ИТОГ КАК ИТОГ СГРУППИРОВАТЬ ПО ИТОГ.Модель, ИТОГ.ТоварнаяГруппа |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |