Переключение на Главную Страницу Страницы: 1 2 3 [4]  ОтправитьПечать
Очень популярная тема (более 25 ответов) Ускорить проведение документа (число прочтений - 15688 )
Neo
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 327
Зарегистрирован: 12. Ноября 2007
Re: Ускорить проведение документа
Ответ #45 - 09. Февраля 2011 :: 10:51
Печать  
Вариант с джоинами:


ИТЗ=СоздатьОбъект("ИндексированнаяТаблица");
           щийДокумент(),0));
     Recordset.УстановитьТекстовыйПараметр("перУслуга",перУслуга);
     Recordset.УстановитьТекстовыйПараметр("Склад",Склад);
     Recordset.УложитьСписокОбъектов(СписокТоваров,"#СписокТоваров","Товары");
     
     Если ИтогиАктуальны()=1 Тогда
           ДатаРасч="";
     Иначе
           ДатаРасч=":ТекПоз~";
     КонецЕсли;
     
     ФильтрПоТовару="Товар IN (SELECT Val FROM #СписокТоваров)";
     
     ДопСоединения="";
     ДопПоля="";
     
     Если ДокументОснование.Вид()="Счет" Тогда
           Recordset.УстановитьТекстовыйПараметр("ДокОсн",ДокументОснование);
           Recordset.УстановитьТекстовыйПараметр("ДокОснСклад",ДокументОснование.Склад);
           ДопСоединения=ДопСоединения+"
           |LEFT JOIN
           |$РегистрОстатки.РезервыТоваров("+ДатаРасч+",,"+ФильтрПоТовару+" AND Склад=:ДокОснСклад AND Счет=:ДокОсн~,(Товар),(Количество)) as РегРез ON Рег.Товар=РегРез.Товар";
           ДопПоля=ДопПоля+",
           |РегРез.КоличествоОстаток AS РезКол";
     КонецЕсли;
     
     Если фАктуальность=1 Тогда
           //Общие остатки
           ДопСоединения=ДопСоединения+"
           |LEFT JOIN
           ство)) as Рег1 ON Рег.Товар=Рег1.Товар";
           ДопПоля=ДопПоля+",
           |Рег1.КоличествоОстаток AS ОбщКол";
           //Общий путь
           ДопСоединения=ДопСоединения+"
           |LEFT JOIN
           ество)) as РегП ON Рег.Товар=РегП.Товар";
           ДопПоля=ДопПоля+",
           |РегП.КоличествоОстаток AS ОбщПуть";
           //Общие резервы
           ДопСоединения=ДопСоединения+"
           |LEFT JOIN
           ство)) as РегРез1 ON Рег.Товар=РегРез1.Товар";
           ДопПоля=ДопПоля+",
           |РегРез1.КоличествоОстаток AS ОбщРезКол";
     КонецЕсли;
     
*** *** ***

     ТекстЗапроса="
     |SELECT
     |Рег.Товар as [Товар $Справочник.Товары],
     |Рег.КоличествоОстаток as [Ост],
     |РегПарт.КоличествоОстаток AS СебестКол,
     |РегПарт.СуммаУпрОстаток AS СебестУпр,
     |РегПарт.СуммаРубОстаток AS СебестРуб"
     +ДопПоля+"
     |FROM
     |$РегистрОстатки.ОстаткиТоваров("+ДатаРасч+",,"+ФильтрПоТовару+" AND Склад=:Склад,(Товар),(Количество)) as Рег
     |LEFT JOIN
     тво,СуммаУпр,СуммаРуб)) as РегПарт ON Рег.Товар=РегПарт.Товар
     |LEFT JOIN
     |$Справочник.Товары as СпрТов ON Рег.Товар=СпрТов.ID"
     +ДопСоединения+"
     |WHERE
     |$СпрТов.ВидТовара<>:перУслуга
     |";
     
     RecordSet.ВыполнитьИнструкцию(ТекстЗапроса, ИТЗ);
  
Наверх
 
IP записан
 
Neo
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 327
Зарегистрирован: 12. Ноября 2007
Re: Ускорить проведение документа
Ответ #46 - 09. Февраля 2011 :: 10:53
Печать  
Вариант с юнионами:

ИТЗ=СоздатьОбъект("ИндексированнаяТаблица");
           щийДокумент(),0));
     Recordset.УстановитьТекстовыйПараметр("перУслуга",перУслуга);
Recordset.УстановитьТекстовыйПараметр("Склад",Склад);
     Recordset.УложитьСписокОбъектов(СписокТоваров,"#СписокТоваров","Товары");
     
     Если ИтогиАктуальны()=1 Тогда
           ДатаРасч="";
     Иначе
           ДатаРасч=":ТекПоз~";
     КонецЕсли;
     
     ФильтрПоТовару="Товар IN (SELECT Val FROM #СписокТоваров)";
     
     ДопСоединения="";
     ДопПоля="";
     
     Если ДокументОснование.Вид()="Счет" Тогда
           Recordset.УстановитьТекстовыйПараметр("ДокОсн",ДокументОснование);
           Recordset.УстановитьТекстовыйПараметр("ДокОснСклад",ДокументОснование.Склад);
           ДопСоединения=ДопСоединения+"
           |UNION ALL
           |SELECT
           |РегРез.Товар as [Товар],
           |0 as [Ост],
           |0 AS СебестКол,
           |0 AS СебестУпр,
           |0 AS СебестРуб,
           |0 AS ОбщКол,
           |0 ОбщПуть,
           |0 AS ОбщРезКол,
           |РегРез.КоличествоОстаток AS РезКол
           |FROM
           |$РегистрОстатки.РезервыТоваров("+ДатаРасч+",,"+ФильтрПоТовару+" AND Склад=:ДокОснСклад AND Счет=:ДокОсн~,(Товар),(Количество)) as РегРез";
           ДопПоля=ДопПоля+",
           |Sum(ВложЗапрос.РезКол) AS РезКол";
     КонецЕсли;
     
     ТекстЗапроса="
     |SELECT
     |ВложЗапрос.Товар as [Товар $Справочник.Товары],
     |Sum(ВложЗапрос.Ост) as [Ост],
     |Sum(ВложЗапрос.СебестКол) AS СебестКол,
     |Sum(ВложЗапрос.СебестУпр) AS СебестУпр,
     |Sum(ВложЗапрос.СебестРуб) AS СебестРуб,
     |Sum(ВложЗапрос.ОбщКол) AS ОбщКол,
     |Sum(ВложЗапрос.ОбщПуть) AS ОбщПуть,
     |Sum(ВложЗапрос.ОбщРезКол) AS ОбщРезКол"
     +ДопПоля+"
     |FROM
     |
     |(SELECT
     |Рег.Товар as [Товар],
     |Рег.КоличествоОстаток as [Ост],
     |0 AS СебестКол,
     |0 AS СебестУпр,
     |0 AS СебестРуб,
     |0 as ОбщКол,
     |0 as ОбщПуть,
     |0 as ОбщРезКол,
     |0 as РезКол
     |FROM
     |$РегистрОстатки.ОстаткиТоваров("+ДатаРасч+",,"+ФильтрПоТовару+" AND Склад=:Склад,(Товар),(Количество)) as Рег
     |UNION ALL
     |SELECT
     |РегПарт.Товар as [Товар],
     |0 as [Ост],
     |РегПарт.КоличествоОстаток AS СебестКол,
     |РегПарт.СуммаУпрОстаток AS СебестУпр,
     |РегПарт.СуммаРубОстаток AS СебестРуб,
     |0 as ОбщКол,
     |0 as ОбщПуть,
     |0 as ОбщРезКол,
     |0 as РезКол
     |FROM
     тво,СуммаУпр,СуммаРуб)) as РегПарт
     |UNION ALL
     |SELECT
     |Рег1.Товар as [Товар],
     |0 as [Ост],
     |0 AS СебестКол,
     |0 AS СебестУпр,
     |0 AS СебестРуб,
     |Рег1.КоличествоОстаток AS ОбщКол,
     |0 as ОбщПуть,
     |0 as ОбщРезКол,
     |0 as РезКол
     |FROM
     ство)) as Рег1
     |UNION ALL
     |SELECT
     |РегП.Товар as [Товар],
     |0 as [Ост],
     |0 AS СебестКол,
     |0 AS СебестУпр,
     |0 AS СебестРуб,
     |0 AS ОбщКол,
     |РегП.КоличествоОстаток AS ОбщПуть,
     |0 as ОбщРезКол,
     |0 as РезКол
     |FROM
     ество)) as РегП
     |UNION ALL
     |SELECT
     |РегРез1.Товар as [Товар],
     |0 as [Ост],
     |0 AS СебестКол,
     |0 AS СебестУпр,
     |0 AS СебестРуб,
     |0 AS ОбщКол,
     |0 ОбщПуть,
     |РегРез1.КоличествоОстаток AS ОбщРезКол,
     |0 as РезКол
     |FROM
     ство)) as РегРез1"
     +ДопСоединения+"
     |) as ВложЗапрос
     |GROUP BY
     |ВложЗапрос.Товар
     |";
     
     RecordSet.ВыполнитьИнструкцию(ТекстЗапроса, ИТЗ);
  
Наверх
 
IP записан
 
Satans Claws
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 721
Зарегистрирован: 29. Ноября 2010
Re: Ускорить проведение документа
Ответ #47 - 09. Февраля 2011 :: 12:03
Печать  
По Джойнам:

1) убери ФильтрПоТоварам из каждого запроса по регистрам, которые цепляешь через Left Join.
Скуль сам разберется, как ему оптимизировать эти (ведомые) выборки, глядя на результат ведущей выборки.

2) Попробуй вместо
ФильтрПоТовару="Товар IN (SELECT Val FROM #СписокТоваров)";
сделать так:
ФильтрПоТовару="Товар IN (SELECT $ДокТЧ.Товар From $ДокументСтроки.Реализация ДокТЧ (Nolock) Where IDDoc = :идТекДок)";
где идТекДок - это, есно, ссылка на проводимый документ (ну и вид дока скорректируй, при необходимости)



Юнионы же мне принципиально нравятся меньше, ибо если какого-то товара на рег.ОстаткиТоваров нет вообще - то с джойном у оптимизатора есть шансы это узреть и скорректировать фильтр для ведомых таблиц джойнов.
  
Наверх
 
IP записан
 
Neo
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 327
Зарегистрирован: 12. Ноября 2007
Re: Ускорить проведение документа
Ответ #48 - 09. Февраля 2011 :: 12:47
Печать  
И то, и другое негативным образом повлияло на скорость. В особенности, когда убрал условие на товар из ВТ, раза в 1,5-2 замедлилось...
  
Наверх
 
IP записан
 
Neo
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 327
Зарегистрирован: 12. Ноября 2007
Re: Ускорить проведение документа
Ответ #49 - 09. Февраля 2011 :: 12:53
Печать  
Вообще, по моим наблюдениям, когда встречаются по сути дублирующие условия внутри ВТ и вовне (например, при JOIN ON), то это не снижает скорость. А если убрать условие из ВТ, то замедление наблюдается...
  
Наверх
 
IP записан
 
Satans Claws
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 721
Зарегистрирован: 29. Ноября 2010
Re: Ускорить проведение документа
Ответ #50 - 09. Февраля 2011 :: 12:57
Печать  
Ок
Оставляем условие "Товар IN (SELECT Val FROM #СписокТоваров)", но делаем его таким образом;

"select
$ДокТЧ.Товар Val
Into [#СписокТоваров]
from
$ДокументСтроки.Реализация ДокТЧ (nolock)
Left Join $Справочник.Товары Товары (nolock) on Товары.ID = $ДокТЧ.Товар
Where
ДокТЧ.ID = :идЭтотДок
And Товары.ВидТовара != :ВидУслуга
"

а в конце не забываем сделать
"Drop Table [#СписокТоваров]".
(а в идеале - вместо имени таблицы "СписокТоваров" используем, например, GUID)

Соттветственно, никаких УложитьСписокОбъектов() не нужно.
  
Наверх
 
IP записан
 
Neo
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 327
Зарегистрирован: 12. Ноября 2007
Re: Ускорить проведение документа
Ответ #51 - 10. Февраля 2011 :: 10:29
Печать  
Ну, чем в (45) стало побыстрее, но все равно медленнее гораздо, чем штатное получение остатков с помощью ОстаткиПолучить()...
  
Наверх
 
IP записан
 
Neo
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 327
Зарегистрирован: 12. Ноября 2007
Re: Ускорить проведение документа
Ответ #52 - 10. Февраля 2011 :: 10:38
Печать  
Вообщем из всех вариантов, которые я перепробовал, получается, что по скорости:

- Самый быстрый - это штатное получение остатков с помощью ОстаткиПолучить().
- далее идет вариант из (27).
- вариант с джоинами с учетом (50).
- вариант с джоинами.
- вариант с юнионами.

Первый вариант процентов на 30 выше второго и значительно выше остальных.
  
Наверх
 
IP записан
 
Anatol
Senior Member
****
Отсутствует


тыц, пыц, тыц!!!

Сообщений: 412
Зарегистрирован: 24. Апреля 2009
Re: Ускорить проведение документа
Ответ #53 - 11. Февраля 2011 :: 09:56
Печать  
Neo писал(а) 10. Февраля 2011 :: 10:38:
Вообщем из всех вариантов, которые я перепробовал, получается, что по скорости:

- Самый быстрый - это штатное получение остатков с помощью ОстаткиПолучить().
- далее идет вариант из (27).
- вариант с джоинами с учетом (50).
- вариант с джоинами.
- вариант с юнионами.

Первый вариант процентов на 30 выше второго и значительно выше остальных.


1 а ты считаешь время вместе с расчетом регистра?
2 что ты вообше хочешь получить? причем здесь партии, товары в пути и прочее...
3 не проще поститать все отдельно, а потом слить в одну таблицу или следать на подзапросах?
  
Наверх
wwwICQ  
IP записан
 
Neo
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 327
Зарегистрирован: 12. Ноября 2007
Re: Ускорить проведение документа
Ответ #54 - 11. Февраля 2011 :: 10:15
Печать  
Цитата:
1 а ты считаешь время вместе с расчетом регистра?
2 что ты вообше хочешь получить? причем здесь партии, товары в пути и прочее...


Считаю я очень просто. Беру модуль проведения, замеряю, за сколько он в среднем проводится. Комментирую все штатные расчеты остатков. Вместо них вставляю те запросы, что выше приводил. Еще раз замеряю и сравниваю, что быстрее.
  
Наверх
 
IP записан
 
Satans Claws
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 721
Зарегистрирован: 29. Ноября 2010
Re: Ускорить проведение документа
Ответ #55 - 11. Февраля 2011 :: 11:47
Печать  
А можешь целиком кинуть модуль проведения документа? (лучше в видет аттача текстового файла)?
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: 1 2 3 [4] 
ОтправитьПечать