|   |   | 
| 
 | Оптимизация запроса или что-то еще? | ☑ | ||
|---|---|---|---|---|
| 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 ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ ИТОГ.ТоварнаяГруппа, ИТОГ.Модель, СУММА(ИТОГ.Количество) КАК Количество ИЗ ИТОГ КАК ИТОГ СГРУППИРОВАТЬ ПО ИТОГ.Модель, ИТОГ.ТоварнаяГруппа | 
 
 | Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |