Реклама на этом месте
Форум 1С
Форум 1С
Программистам. Бухгалтерам. Администраторам. Пользователям
Задай вопрос - получи решение проблемы. Без троллинга и флуда.
14 Ноя 2018, 01:51
МультиВход
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Не получили письмо с кодом активации?
 
collapse

Автор Тема: Вторник. Вопрос 5  (Прочитано 55174 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн trad_

  • *
  • Сообщений: 21
  • РЕПУТАЦИЯ: 0
  • Регистрация: 2013-03-07
  • Сайт: 
  • Профессия: Программист 7.7
Re: Вторник. Вопрос 5
« Ответ #20: 12 Мар 2013, 12:17 »
Выгоднее к каждому документу присоединить записи регистра сведений по ключевым полям индекса чем получать выборку всех данных регистра и прицеплять результат такой выборки.
Поэтому:
сначала получаем ПТиУ сразу ограничивая по типу договора,
затем присоединяем регистр по ключевым полям,
так как регистр присоединен не по полному ключу, то ключ может быть не уникальным, и может присоединиться более одной записи, поэтому группируем
после группировки отсекаем по условиям суммы

ps Следует обратить внимание на то, что:
- при отсутствии соответствующих записей в регистре,
выражение СУММА(ЛимитыКредиторскойЗадолженности.Сумма) может не иметь значения, то есть быть NULL.
Сравнение с отсутствующим значением всегда Ложь.

- регистр отбирается по организации, а документы ПТиУ не отбираются.
Поэтому регистр в запросе будет "работать" только для части документов. Для другой части сумма лимита будет null.

Исправлять не стал, так как такое "поведение" заложено в исходном запросе.

ВЫБРАТЬ
    ПоступлениеТоваровИУслуг.Ссылка,
    МАКСИМУМ(ПоступлениеТоваровИУслуг.Номер) КАК Номер,
    МАКСИМУМ(ПоступлениеТоваровИУслуг.Договор) КАК Договор,
    МАКСИМУМ(ПоступлениеТоваровИУслуг.Контрагент) КАК Контрагент,
    МАКСИМУМ(ПоступлениеТоваровИУслуг.Организация) КАК Организация,
    МАКСИМУМ(ПоступлениеТоваровИУслуг.Сумма) КАК Сумма,
    МАКСИМУМ(ПоступлениеТоваровИУслуг.Дата) КАК Дата
ИЗ
    Документ.ПоступлениеТоваровИУслуг КАК ПоступлениеТоваровИУслуг
    ЛЕВОЕ СОЕДИНЕНИЕ
РегистрСведений.ЛимитыКредиторскойЗадолженности КАК ЛимитыКредиторскойЗадолженности
ПО ЛимитыКредиторскойЗадолженности.Контрагент = ПоступлениеТоваровИУслуг.Контрагент
И ЛимитыКредиторскойЗадолженности.Договор = ПоступлениеТоваровИУслуг.Договор
И ЛимитыКредиторскойЗадолженности.Организация = &Организация
ГДЕ
    (ПоступлениеТоваровИУслуг.Договор.ДоговорСПодрядчиком = ИСТИНА
ИЛИ ПоступлениеТоваровИУслуг.Договор.ДоговорСПоставщиком = ИСТИНА)
СГРУППИРОВАТЬ ПО
ПоступлениеТоваровИУслуг.Ссылка
ИМЕЮЩИЕ
(МАКСИМУМ(ПоступлениеТоваровИУслуг.Сумма) < &МинимальнаяСуммаЗадолженности
ИЛИ МАКСИМУМ(ПоступлениеТоваровИУслуг.Сумма) < СУММА(ЛимитыКредиторскойЗадолженности.Сумма))


Оффлайн Evgeny

  • *
  • Сообщений: 46
  • РЕПУТАЦИЯ: 0
  • Регистрация: 2011-02-09
  • Сайт: 
  • Профессия: Разработчик 1С
Re: Вторник. Вопрос 5
« Ответ #21: 12 Мар 2013, 12:24 »
запрос 1 : выделить таблицу ПТУ в во временную сделать отбор по организации
запрос 2 : во второй соединить временную с РС.ЛимитыКредиторскойЗадолженности, сделать левое соединение по Контрагенту и Договору, ограничить выборку условием и параметром.
О_о Кто здесь?

Оффлайн ErrorEd88

  • *
  • Сообщений: 30
  • РЕПУТАЦИЯ: 0
  • Регистрация: 2010-05-28
  • Сайт: 
Re: Вторник. Вопрос 5
« Ответ #22: 12 Мар 2013, 12:34 »
Регистр ЛимитыКредиторскойЗадолженности нужно поместить во временную таблицу (или сделать вложенный запрос), после этого таблицу уже можно присоединять к документу поступление товаров и услуг левым соединением.
Я ошибся

Оффлайн no_limits

  • *
  • Сообщений: 38
  • РЕПУТАЦИЯ: 0
  • Регистрация: 2011-11-23
  • Сайт: 
  • Профессия: Разработчик 1С
Re: Вторник. Вопрос 5
« Ответ #23: 12 Мар 2013, 12:45 »
Можно вынести
ВЫБРАТЬ
            ЛимитыКредиторскойЗадолженности.Организация КАК Организация,
            ЛимитыКредиторскойЗадолженности.Контрагент КАК Контрагент,
            ЛимитыКредиторскойЗадолженности.Договор КАК Договор,
            СУММА(ЛимитыКредиторскойЗадолженности.Сумма) КАК Сумма
        ИЗ
            РегистрСведений.ЛимитыКредиторскойЗадолженности КАК ЛимитыКредиторскойЗадолженности
        ГДЕ
            ЛимитыКредиторскойЗадолженности.Организация = &Организация
Во временную таблицу и поставить индексацию по полям Организация, контрагент и Договор

Оффлайн heroy

  • *
  • Сообщений: 20
  • РЕПУТАЦИЯ: 0
  • Регистрация: 2012-02-05
  • Сайт: 
  • Профессия: Программист 8.1
Re: Вторник. Вопрос 5
« Ответ #24: 12 Мар 2013, 12:49 »
Примерно так:

ВЫБРАТЬ
    ПТУ.Ссылка,
    ПТУ.Номер,
    ПТУ.Договор,
    ПТУ.Контрагент,
    ПТУ.Организация,
    ПТУ.Сумма,
    ПТУ.Дата
ИЗ
    Документ.ПоступлениеТоваровИУслуг КАК ПТУ      
   ВНУТРЕННЕЕ СОЕДИНЕНИЕ (
      ВЫБРАТЬ
         Лимиты.Контрагент КАК Контрагент,
         Лимиты.Договор КАК Договор,
         СУММА(Лимиты.Сумма) КАК Сумма
      ИЗ
         РегистрСведений.ЛимитыКредиторскойЗадолженности КАК Лимиты
      ГДЕ
         Лимиты.Организация = &Организация
       
      СГРУППИРОВАТЬ ПО
         Лимиты.Контрагент,
         Лимиты.Договор
      ИМЕЮЩИЕ
          СУММА(Лимиты.Сумма) < &МинимальнаяСуммаЗадолженности
   ) как Лимиты
   ПО
      ПТУ.Контрагент = Лимиты.Контрагент
        И ПТУ.Договор = Лимиты.Договор
ГДЕ
   ПТУ.Сумма < Лимиты.Сумма
   И (ПТУ.Договор.ДоговорСПодрядчиком = ИСТИНА ИЛИ ПТУ.Договор.ДоговорСПоставщиком = ИСТИНА)
            

            
            
1. Во вложенном запросе нет смысла группировать по огранизации,
   для группировки будет использоваться ключ по измерениям, поля в нужном порядке + задан четкий предикат по организации
2. Задать дополнительное ограничение по сумме для уменьшения левой таблицы Join,
   и уменьшения шанса эскалации блокировок при параллельной работе, так это перенесенный на более нижний уровень, стоимость операции
   будет меньше так как меньший объем данных   
3. Может показаться что для улучшения быстродействия, посредством уменьшения левой таблицы путем переноса условия
   (ПоступлениеТоваровИУслуг.Договор.ДоговорСПодрядчиком = ИСТИНА
            ИЛИ ПоступлениеТоваровИУслуг.Договор.ДоговорСПоставщиком = ИСТИНА) во вложенный запрос, но это не так,
   это поставит крест на использовании индекса на самой дорогой операции в запросе - группировке, что потянет за собой
   заметное падение быстродействия при увеличение объема данных
4. (ПоступлениеТоваровИУслуг.Сумма < &МинимальнаяСуммаЗадолженности
            ИЛИ ПоступлениеТоваровИУслуг.Сумма < ЛимитыКредиторскойЗадолженности.Сумма) - первую часть перенесли во вложенный запрос,
   итого осталось ПоступлениеТоваровИУслуг.Сумма < ЛимитыКредиторскойЗадолженности.Сумма а так как используется левое соединение и
   не используется ЕстьNULL то в случае отсутствия записи в левой таблицы все условие ГДЕ будет ложь, что эквивалентно поведению
   менее дорогой SQL операции Inner Join, поэтому заменим левое соединение на внутренне (то есть если для контрагента и договора не
   задан лимит в результат он не попадает)
5. знать бы реквизиты договора, можно было бы посмотреть дальше, булево имеет очень низкую селективность и с большой вероятностью
   вместо использования индекса может быть использована операция Table Scan
            

Оффлайн Vit1501

  • ****
  • Сообщений: 360
  • РЕПУТАЦИЯ: 60
  • КПД: 17%
  • Регистрация: 2010-06-05
  • Сайт: 
  • Профессия: Программист 1С
Re: Вторник. Вопрос 5
« Ответ #25: 12 Мар 2013, 12:56 »
1. Переделать вложенный запрос на временную таблицу - рекомендации разработчиков платформы по оптимизации.
2. Добавить отбор по типу договора внутри временной таблицы тоже- чем меньше записей получится во временной таблице, тем быстрее она сформируется и быстрее быдет производится соединение с другой таблицей
3. добавить индекс во временную таблицу для более быстрого соединения двух таблиц
Вот примерный результат
ВЫБРАТЬ
   ЛимитыКредиторскойЗадолженности.организация,
   ЛимитыКредиторскойЗадолженности.контрагент КАК контрагент,
   ЛимитыКредиторскойЗадолженности.Договор,
   СУММА(ЛимитыКредиторскойЗадолженности.сумма) КАК сумма
ПОМЕСТИТЬ ВТЛимиты
ИЗ
   РегистрСведений.ЛимитыКредиторскойЗадолженности КАК ЛимитыКредиторскойЗадолженности
ГДЕ
   ЛимитыКредиторскойЗадолженности.организация = &организация
   И ЛимитыКредиторскойЗадолженности.Договор.ДоговорСПодрядчиком = ИСТИНА
   И ЛимитыКредиторскойЗадолженности.Договор.договорСПоставщиком = ИСТИНА

СГРУППИРОВАТЬ ПО
   ЛимитыКредиторскойЗадолженности.организация,
   ЛимитыКредиторскойЗадолженности.контрагент,
   ЛимитыКредиторскойЗадолженности.Договор

ИНДЕКСИРОВАТЬ ПО
   контрагент
;

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

Оффлайн wok

  • *
  • Сообщений: 21
  • РЕПУТАЦИЯ: 0
  • Регистрация: 2011-09-15
  • Сайт: 
  • Профессия: Бухгалтер
Re: Вторник. Вопрос 5
« Ответ #26: 12 Мар 2013, 13:03 »
Из вложенного запроса убрать поле и группировку "Организация" (т.к. по ней идет отбор). А если предположить, что записи в регистре сведений и документе ПоступлениеТоваровИУслуг один и тот же договор не используется с разными контрагентами, то еще и убрать поле и группировку "Контрагент" из вложенного запроса.
Получится:
ВЫБРАТЬ
    ПоступлениеТоваровИУслуг.Ссылка,
    ПоступлениеТоваровИУслуг.Номер,
    ПоступлениеТоваровИУслуг.Договор,
    ПоступлениеТоваровИУслуг.Контрагент,
    ПоступлениеТоваровИУслуг.Организация,
    ПоступлениеТоваровИУслуг.Сумма,
    ПоступлениеТоваровИУслуг.Дата
ИЗ
    Документ.ПоступлениеТоваровИУслуг КАК ПоступлениеТоваровИУслуг
        ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
            ЛимитыКредиторскойЗадолженности.Договор КАК Договор,
            СУММА(ЛимитыКредиторскойЗадолженности.Сумма) КАК Сумма
        ИЗ
            РегистрСведений.ЛимитыКредиторскойЗадолженности КАК ЛимитыКредиторскойЗадолженности
        ГДЕ
            ЛимитыКредиторскойЗадолженности.Организация = &Организация
       
        СГРУППИРОВАТЬ ПО
            ЛимитыКредиторскойЗадолженности.Договор) КАК ЛимитыКредиторскойЗадолженности
        ПО ПоступлениеТоваровИУслуг.Договор = ЛимитыКредиторскойЗадолженности.Договор
ГДЕ
    (ПоступлениеТоваровИУслуг.Сумма < &МинимальнаяСуммаЗадолженности
            ИЛИ ПоступлениеТоваровИУслуг.Сумма < ЛимитыКредиторскойЗадолженности.Сумма)
    И (ПоступлениеТоваровИУслуг.Договор.ДоговорСПодрядчиком = ИСТИНА
            ИЛИ ПоступлениеТоваровИУслуг.Договор.ДоговорСПоставщиком = ИСТИНА)

Оффлайн iPach89

  • *
  • Сообщений: 35
  • РЕПУТАЦИЯ: 0
  • Регистрация: 2012-08-16
  • Сайт: 
  • Профессия: Программист 8.1
Re: Вторник. Вопрос 5
« Ответ #27: 12 Мар 2013, 13:32 »
на мой взгляд второе условие лишнее, можно отборку сделать в первом, чтобы не тащить все данные.
ВЫБРАТЬ
    ПоступлениеТоваровИУслуг.Ссылка,
    ПоступлениеТоваровИУслуг.Номер,
    ПоступлениеТоваровИУслуг.Договор,
    ПоступлениеТоваровИУслуг.Контрагент,
    ПоступлениеТоваровИУслуг.Организация,
    ПоступлениеТоваровИУслуг.Сумма,
    ПоступлениеТоваровИУслуг.Дата
ИЗ
    Документ.ПоступлениеТоваровИУслуг КАК ПоступлениеТоваровИУслуг
        ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
            ЛимитыКредиторскойЗадолженности.Организация КАК Организация,
            ЛимитыКредиторскойЗадолженности.Контрагент КАК Контрагент,
            ЛимитыКредиторскойЗадолженности.Договор КАК Договор,
            СУММА(ЛимитыКредиторскойЗадолженности.Сумма) КАК Сумма
        ИЗ
            РегистрСведений.ЛимитыКредиторскойЗадолженности КАК ЛимитыКредиторскойЗадолженности
        ГДЕ
            ЛимитыКредиторскойЗадолженности.Организация = &Организация
            (ПоступлениеТоваровИУслуг.Сумма < &МинимальнаяСуммаЗадолженности
            ИЛИ ПоступлениеТоваровИУслуг.Сумма < ЛимитыКредиторскойЗадолженности.Сумма)
          И    (ПоступлениеТоваровИУслуг.Договор.ДоговорСПодрядчиком = ИСТИНА
            ИЛИ ПоступлениеТоваровИУслуг.Договор.ДоговорСПоставщиком = ИСТИНА)
        СГРУППИРОВАТЬ ПО
            ЛимитыКредиторскойЗадолженности.Организация,
            ЛимитыКредиторскойЗадолженности.Контрагент,
            ЛимитыКредиторскойЗадолженности.Договор) КАК ЛимитыКредиторскойЗадолженности
        ПО ПоступлениеТоваровИУслуг.Контрагент = ЛимитыКредиторскойЗадолженности.Контрагент
            И ПоступлениеТоваровИУслуг.Договор = ЛимитыКредиторскойЗадолженности.Договор
   

Оффлайн lobster13

  • *
  • Сообщений: 39
  • РЕПУТАЦИЯ: 0
  • Регистрация: 2011-10-03
  • Сайт: 
  • Профессия: Программист 1С
Re: Вторник. Вопрос 5
« Ответ #28: 12 Мар 2013, 13:43 »
ВЫБРАТЬ
    ЛимитыКредиторскойЗадолженности.Контрагент КАК Контрагент,
    ЛимитыКредиторскойЗадолженности.Договор КАК Договор,
    ЕстьNULL(СУММА(ЛимитыКредиторскойЗадолженности.Сумма),0) КАК Сумма // Обработаем NULL
ПОМЕСТИТЬ Лимиты
    ИЗ
    РегистрСведений.ЛимитыКредиторскойЗадолженности КАК ЛимитыКредиторскойЗадолженности
ГДЕ
    ЛимитыКредиторскойЗадолженности.Организация = &Организация
       
СГРУППИРОВАТЬ ПО
    ЛимитыКредиторскойЗадолженности.Контрагент,
    ЛимитыКредиторскойЗадолженности.Договор ;
/////////////////////////////////////////////////////////
ВЫБРАТЬ
    ПоступлениеТоваровИУслуг.Ссылка,
    ПоступлениеТоваровИУслуг.Номер,
    ПоступлениеТоваровИУслуг.Договор,
    ПоступлениеТоваровИУслуг.Контрагент,
    ПоступлениеТоваровИУслуг.Организация,
    ПоступлениеТоваровИУслуг.Сумма,
    ПоступлениеТоваровИУслуг.Дата
ИЗ
    Документ.ПоступлениеТоваровИУслуг КАК ПоступлениеТоваровИУслуг
        ЛЕВОЕ СОЕДИНЕНИЕ Лимиты КАК ЛимитыКредиторскойЗадолженности
        ПО ПоступлениеТоваровИУслуг.Контрагент = ЛимитыКредиторскойЗадолженности.Контрагент
            И ПоступлениеТоваровИУслуг.Договор = ЛимитыКредиторскойЗадолженности.Договор
ГДЕ
    (ПоступлениеТоваровИУслуг.Сумма < &МинимальнаяСуммаЗадолженности
            ИЛИ ПоступлениеТоваровИУслуг.Сумма < ЛимитыКредиторскойЗадолженности.Сумма)
    И (ПоступлениеТоваровИУслуг.Договор.ДоговорСПодрядчиком = ИСТИНА
            ИЛИ ПоступлениеТоваровИУслуг.Договор.ДоговорСПоставщиком = ИСТИНА)

//// Уберем из соединение подзапрос и поместим его во временную таблицу ЛИМИТЫ и с ней будем делать соединение.
Поле Организация и группировка по организации не нужны, так как выбираются записи по одной организации. В случае отсутствия записи по контрагенту будет Сумма NULL, учтем это.

Оффлайн cathrine

  • *
  • Сообщений: 20
  • РЕПУТАЦИЯ: 0
  • Регистрация: 2013-03-11
  • Сайт: 
  • Профессия: Программист 1С
Re: Вторник. Вопрос 5
« Ответ #29: 12 Мар 2013, 14:06 »
допускаем, что:
1. те поля, которые мы выбрали в запросе нам действительно необходимы
2. и нам действительно нужна детализация до документов (ссылка)
3. считаем регистр сведений непериодическим

ВЫБРАТЬ
    ПоступлениеТоваровИУслуг.Ссылка,
   // ПоступлениеТоваровИУслуг.Номер, - можно вытащить из ссылка
    ПоступлениеТоваровИУслуг.Договор,
    ПоступлениеТоваровИУслуг.Контрагент,
    ПоступлениеТоваровИУслуг.Организация,
    ПоступлениеТоваровИУслуг.Сумма//,
 //   ПоступлениеТоваровИУслуг.Дата - можно вытащить из ссылка
ИЗ
    Документ.ПоступлениеТоваровИУслуг КАК ПоступлениеТоваровИУслуг
        ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
          //  ЛимитыКредиторскойЗадолженности.Организация КАК Организация,
//-не используется в необходимых полях, и с учетом левого соединения, и отбора
// по организации в регистре сведений, является лишним
            ЛимитыКредиторскойЗадолженности.Контрагент КАК Контрагент,
            ЛимитыКредиторскойЗадолженности.Договор КАК Договор,
            СУММА(ЛимитыКредиторскойЗадолженности.Сумма) КАК Сумма
        ИЗ
            РегистрСведений.ЛимитыКредиторскойЗадолженности КАК ЛимитыКредиторскойЗадолженности
        ГДЕ
            ЛимитыКредиторскойЗадолженности.Организация = &Организация
       
        СГРУППИРОВАТЬ ПО
         //   ЛимитыКредиторскойЗадолженности.Организация, -//-
            ЛимитыКредиторскойЗадолженности.Контрагент,
            ЛимитыКредиторскойЗадолженности.Договор) КАК ЛимитыКредиторскойЗадолженности
        ПО ПоступлениеТоваровИУслуг.Контрагент = ЛимитыКредиторскойЗадолженности.Контрагент
            И ПоступлениеТоваровИУслуг.Договор = ЛимитыКредиторскойЗадолженности.Договор
ГДЕ
    (ПоступлениеТоваровИУслуг.Сумма < &МинимальнаяСуммаЗадолженности
            ИЛИ ПоступлениеТоваровИУслуг.Сумма < ЛимитыКредиторскойЗадолженности.Сумма)
    И (ПоступлениеТоваровИУслуг.Договор.ДоговорСПодрядчиком = ИСТИНА
            ИЛИ ПоступлениеТоваровИУслуг.Договор.ДоговорСПоставщиком = ИСТИНА)


Теги:
 


* Реклама

* Поиск

* Последние задачи на разработку (фриланс)

* Реклама

* Последние вакансии

* Топ 10 авторов за месяц

oleg-x
64 Сообщений
wise wise
58 Сообщений
AIFrame AIFrame
50 Сообщений
alexandr_ll
46 Сообщений
Геннадий ОбьГЭС Геннадий ОбьГЭС
43 Сообщений
alex0402
41 Сообщений
LexaK
32 Сообщений
BuhRust
28 Сообщений
andron81_81
24 Сообщений
MuI_I_Ika MuI_I_Ika
22 Сообщений

* Кто онлайн

  • Точка Гостей: 133
  • Точка Скрытых: 0
  • Точка Пользователей: 0

Нет пользователей онлайн.

* Облако тэгов

* Форум 1С с мобильного

* Инструменты

* Дополнительно

Поиск

 
SimplePortal 2.3.5 © 2008-2012, SimplePortal