|
v7: Оптимизировать процедуру 1c7.7_SQL | ☑ | ||
---|---|---|---|---|
0
_traktor_
02.10.23
✎
22:37
|
Обьем базы 9 гб
Сервер: SQL2008+Server2016(ram64Gb+RAID10)+LAN_1GB Клиенты: i5+ram8Gb Достаточно долгое формирование обработки, более 10 минут. https://cloud.mail.ru/public/3u7V/9z6yuyqKg Какие варианты оптимизации кода ? |
|||
1
Злопчинский
02.10.23
✎
22:48
|
тебе забесплатно отрефакторить/переписать?
. вариант оптимизации самый первый если владеешь - прямые запросы. . 10 минут ни о чем не говорит. что в итоге этих 10 минут получается? простыня на 100 тыс строк? |
|||
2
Злопчинский
02.10.23
✎
22:49
|
штатно тоже можно ускорить, но надо СМОТРЕТЬ ПРЕДМЕТНО если нужен хороший результат.
|
|||
3
Злопчинский
02.10.23
✎
22:50
|
О... это еще на бухкомпоненте...
|
|||
4
Харлампий Дымба
02.10.23
✎
22:51
|
Круть. А кто-нибудь помнит что означали {} в условии запроса ? Это 7.0 или 7.5 было.
Сейчас попробую чуть-чуть посмотреть, без советов переписать всё на прямые запросы. |
|||
5
Злопчинский
02.10.23
✎
22:54
|
занятная конструкция, никогда не использовал...
Условие ({СокрЛП(ВыбАртикул)} в СокрЛП(Артикул)) . почему не тупо на равенство строк? |
|||
6
Злопчинский
02.10.23
✎
22:56
|
(4) я вообще хз что такое с фигурными скобками в части синтаксиса запросов, никогда не юзал
|
|||
7
Злопчинский
02.10.23
✎
23:00
|
(0) Попробовать: все переменные запроса если они не используются в группировках/условиях - убрать. В коде их дергать через точку там где они нужны.
|
|||
8
Злопчинский
02.10.23
✎
23:02
|
Группировка Товар Без групп;
в коде убрать проверки Запрос.Товар.ЭтоГруппа()=1 |
|||
9
Злопчинский
02.10.23
✎
23:04
|
Многоэтажную хрень если и циклов с анализом флажков группировок переделать нахрен по образу и подобию как в ТиС список значений группировок (Отчет ОстаткиТМЦ), разбираться в этой лапше совсем не хочется
|
|||
10
Злопчинский
02.10.23
✎
23:07
|
Убрать нахрен консруктцию Таб.ПрисоединитьСекцию - это тормозная штука при выводе очета. Проще сделать два макета - с короткой строкой и с длинной строкой и задавать исходный макет в зависимости от флажков.
|
|||
11
Злопчинский
02.10.23
✎
23:08
|
Убрать работу с областями, это тоже тормозная штука.
оформит сразу как надо - даже если попроще пусть убдет Обл = Таб.Область(НачСтрока,7); Обл.РамкаСправа(3); |
|||
12
Злопчинский
02.10.23
✎
23:10
|
ну и хорошо бы привести пример замера, на чем жрется время
|
|||
13
Злопчинский
02.10.23
✎
23:13
|
хз что там у вас в
ПолучитьЦенуТМЦ() если периодика там дергается - то и тут тормоза будут, особенно если таких операций много или переписывать или переходить на объект "Периодический" - дает прирост при работе в периодическими реквизитами ~25% |
|||
14
Злопчинский
02.10.23
✎
23:15
|
чисто приколоться.. надо было еще сложнее написать..
. //******************************************* Процедура ПриВыбреМестаХранения() Если МестоХранения.Выбран() = 0 Тогда Форма.ПоСкладам.Видимость(1); Иначе Форма.ПоСкладам.Видимость(0); КонецЕсли; КонецПроцедуры . Форма.ПоСкладам.Видимость(1-МестоХранения.Выбран()); |
|||
15
Злопчинский
02.10.23
✎
23:20
|
в ВыбТовары = Только товары, группы не класть и попробовать вместо
"Условие (Товар в {ВыбТовары});" . условие убрать фильтровать при обходе группировки по товарам по типу Если ВыбТовары.НайтиЗначение(Запрос.Товар)=0 Тогда Продолжить; КонецЕсли; . может получиться охеренный итоговый прирост скорости выполнения |
|||
16
Злопчинский
03.10.23
✎
10:28
|
на сем мое волонтерсов закончилось. думать влом.
Харлампий Дымба накинет еще, может и отчет перепишет.. он такой.. |
|||
17
Харлампий Дымба
02.10.23
✎
23:35
|
Всё ниже - моё мнение, пусть меня поправят, если не прав.
Все вот такие условия в запросе: "Условие (ПустаяСтрока(ТоварнаяГруппа)=0);" плохи вызовом функций 1С, лучше задать ПустаяТоварнаяГруппа=ПолучитьПустоеЗначение("Справочник.ТоварныеГруппы") и в условии писать Условие (ТоварнаяГруппа<>ПустаяТоварнаяГруппа); Все вот такие условия Условие(Товар.ВидНоменклатуры = ВидНоменклатуры) хуже чем ВидНоменклатурыТовара = Регистр.ОстаткиТоваров.Номенклатура.ВидНоменклатуры; Условие(ВидНоменклатурыТовара = ВидНоменклатуры) Если в группировках - элементы справочник, а группы не нужны - пиши "Группировка Склад без групп" если не важен порядок и не планируешь испоьзовать потом наименование элементов из группировки - пиши "Группировка Склад без групп без Упорядочивания", если планируешь использовать наименование Упорядочить по Склад.Наименование Запрос.Товар.ЭтоГруппа() плохо тем, что ты впустую считываешь объект из базы (он тебе дальше не нужен) - пиши Запрос.ЭтоГруппа("Товар") ПолучитьЦенуТМЦ(Запрос.Товар,ДатаОтчета) - не вижу что в коде, но очень подозреваю, что там что-то типа Товар.Цена.Получить(ДатаОтчета) лучше переписать гл_П1.ИспользоватьОбъект("Цена",Товар); Возврат гл_П1.ЗначениеНаДату(НаДату); где глП_1 - глобальная переменная, которая инициализируется в глобальном модуле (не в функции ПолучитьЦенуТМЦ!), т.е. в конце глобального модуля П=СоздатьОбъект("Периодический"); В макете отчета не пиши Запрос.Товар.Наименование во-первых используй уже подготовленную переменную, а в ячейку пиши уже ее ПечТовар=Запрос.Товар.Наименование в группировке в запросе напиши Упорядочить По Товар.Наименование а ячейке присваивай ПечТовар=Запрос.ЗначениеУпорядочивания(1) либо в запросе сразу делай переменную АртикулТовара=Запрос.Товар.Артикул и пиши ПечАртикул=Запрос.АртикулТовара Запрос.Товар.Цвет.Наименование - ооооочень долго перепиши все так, чтобы по возможности не было Реквизит=Запрос.ЭлементСправочника.РеквизитСправочника если нельзя обойтись без этого, тогда хотя бы так: Элемент=Запрос.ЭлементСправочника; Реквизит=Элемент.РеквизитСправочника; форматирование в ячейках таблиц типа #N12.2. - можно оставить как есть, там выиграша не будет. можно в принципе и текст запроса составлять так, чтобы не получать лишних реквизитов - если не поставили группировку или отбора по складу - то Склад = Регистр.ОстаткиТоваров.МестаХранения; можно убирать по бухитогам вопросов нет Воспользуйся замером производительности в отладчике - включи часы в начала отчета, выключи после окончания, посмотри время Это основное, что ты можешь выжать из обычных 1совских отчетов |
|||
18
Харлампий Дымба
02.10.23
✎
23:37
|
(16) Хехе - чуть не один в один)
|
|||
19
Злопчинский
02.10.23
✎
23:41
|
(18) а что делать... Если в руках молоток - весь мир состоит из гвоздей...
|
|||
20
Djelf
03.10.23
✎
11:46
|
(6)
(0) Попробуй Запрос.ВключитьSQL(0); Смутно помнится, что на тупящих запросах на sql базах это помогало. |
|||
21
Харлампий Дымба
03.10.23
✎
10:54
|
(20) Это про скобки в 8. В 7.7 же, насколько помнится, скобки остались как анахронизм от версии 7.0 - ими предполагалось выделять переменные модуля, используемые в запросе, в отличие от переменных запроса. А в 7.0 они попали так как широко использовались в 6.0 для указания макроимени (ссылки) субконто типовой операции..
К 7.7 решили, что скобки - лишнее, но синтаксис оставили для совместимости. Попробовал сейчас, думал что можно будет с помощью этих скобок иметь возможность использовать одинаковые имена для переменных запрос и модуля, типа "Условие (Товар в {Товар})", но нет, не работает. Так что скобки не нужны от слова "совсем". (20) Запрос.ВключитьSQL(0) - как правило, наоборот резко замедляет скорость формирования запроса. Этот переключатель, чтобы сформировать запрос, не как sql-ный, а как dbf-ный. Использовался, видимо самой 1С, для отладки, чтобы понять не косячит ли sql-ный запрос и даёт ли те же данные, что и dbf-ный. В некоторых случаях как раз и помогает обойти оставшиеся косяки sql-ных запросов, например Условие (ДатаДок в СписокДат) в sql у меня не работает, а в DBF - без проблем. Поэтому надо или Запрос.ВключитьSQL(0); или Условие (СписокДат.НайтиЗначение(ДатаДок)>0) И второе всё равно работает гораздо быстрее. (0) Ах да, ещё у тебя там "Группировка Партия" - убери для тех типов цен, где она не нужна. Тут хорошая прибавка будет. Ну и в ТЗ в цикле группировки по партиям зачем пихать каждый раз .НоваяСтрока с тем же товаром? Чтоб потом делать ТЗ.Свернуть с миллионом строк? Лучше посчитай в цикле итоговую сумму по товару, и потом добавь в ТЗ одной строкой. А вообще - "Замер производительности" и смотри на чем проигрываешь, может у тебя Запрос.Выполнить - 10% от времени, а остальное это неоптимальный алгоритм обработки полученных данных. |
|||
22
Djelf
03.10.23
✎
11:36
|
(21) Ну да, для 8ки, но что-то схожее видимо есть..
В том то и дело что "как правило", попробовать все равно стоит. |
|||
23
Злопчинский
03.10.23
✎
13:11
|
(21) Условие (ДатаДок в СписокДат) в sql у меня не работает
- проверь когда в списке одно значение и когда несколько |
|||
24
vladmenleo
03.10.23
✎
13:27
|
(0) Переписать все на прямой запрос из 1с++. Лучше полчаса потерять, зато потом за 5 минут долететь (с)
|
|||
25
Chai Nic
03.10.23
✎
13:31
|
(24) +1
Черные запрос на sql часто работает неадекватно - вытягивает половину базы в temp в виде dbf-файлов и дальше обрабатывает уже их. Сталкивался с подобным отчетом по продажам, который формировался чуть ли не полчаса. Простой перебор документов был на несколько порядков быстрее. |
|||
26
Злопчинский
03.10.23
✎
13:32
|
(25) это зависит от того как написаны условия. если "неправильно" - тогда тянется результат "запроса" в темп и на него дополнительно накатывают условия и потом выдают как результат "запроса"
|
|||
27
Злопчинский
03.10.23
✎
13:36
|
(26) .. хотя это я на дбф наблюдал, а вот как на скуле - хз...
|
|||
28
vladmenleo
03.10.23
✎
13:37
|
(26) Именно так, все от условий. Частенько оптимально засунуть результат во временную таблицу на сервере, а потом из нее выбрать по условию
|
|||
29
vladmenleo
03.10.23
✎
13:43
|
(26) Ступил, речь про черный запрос. Почти пять лет в конторе, все на прямых запросах
|
|||
30
Chai Nic
03.10.23
✎
13:52
|
(27) А на sql так же, только хуже))
|
|||
31
Злопчинский
03.10.23
✎
14:04
|
я столнулся с тем что на скуле
Условие(Номенклатура в Сзноменклатура); - адски тормозило. проще было собрать запрос без фильтра по товарам (даже если товаров было очень много) и уже при обходе результат запроса фильтровать вручную через СЗНоменклатура.НайтиЗначение(Запрос.Номенклатура). . почему так - хз, может как-то криво секретный релиз поставлен или еще что... |
|||
32
АгентБезопасной Нацио
03.10.23
✎
14:43
|
(25) ага, а все потому, что sql в клюшках используется как тупое таблицохранилище. поэтому оно, грубо говоря, тянет весь селект-лист на клиента в дбф (фильтруя только, емнип, по общим реквизитам доков), а уже там строит индексы для других отборов.
(24) категорически согласен. |
|||
33
Злопчинский
03.10.23
✎
15:28
|
(24) (32) Ну дык и помогите страждущему ;-)
|
|||
34
Arbuz
03.10.23
✎
15:37
|
(24) В оригинале было:
Лучше день потерять, зато потом за 5 минут долететь (с) Я не знаю как там на mssql обстоят дела, но прямые на dbf через 1sqlite у меня дают типичный выигрыш более двух порядков (я где-то отмечал, что в ТиС на запросе в СписаниеТМЦ я получил выигрыш в 8000 раз). Уже только это заставило меня не думать о чорных запросах совсем никогда. Не считая того, что в прямой запрос можно переложить значительную часть логики постобработки, что ещё ускоряет итог. Бедные снеговиководы, через плечо заглядывая с неприкрытой жалостью и брезглиговостью на уродские клюшки, так и не могут поверить своим глазам, когда видят, что у меня средняя скорость проведения документа в потоке при очень активных юзерах < 70мс на оборудовании чья производительность уступает паре смарт-чайников. Есть, конечно, БП'шный снеговик куда всё консолидируется из клюшек - удобный, красивый, современный, упитанный, уверенный и лоснящийся. |
|||
35
Злопчинский
03.10.23
✎
15:41
|
(34) я прямые не осилил, только самое простое. Просто надобности не было, не работал я в нагруженных системах с большим количеством пользователей, пичалька...
|
|||
36
АгентБезопасной Нацио
03.10.23
✎
16:16
|
(33)
"-Господи, ну помоги же Абраму выйграть в лотерею! --Да я бы помог, но пусть он хоть раз купит лотерейный билет!" © Я в том смысле, что пусть хотя бы трассировку сделает, определит, где основные тормоза... а то накинул, и пропал.. Да и клюшек под рукой нет, проверить. Запрос-то и руками написать не проблема, но малейший косяк в синтаксисе - и будет бодяга на пару недель, судя по скорости реакции ТСа |
|||
37
vladmenleo
03.10.23
✎
16:39
|
(33) (0) В первом приближении как-то так
ТзЗапрос = СоздатьОбъект("ТаблицаЗначений"); ЗапросДляТЗ = СоздатьОбъект("ODBCRecordSet"); ТекстЗапроса = " |Select | Рег.МестаХранения as [Склад $Справочник.Склады], | Тов.ID as [Товар $Справочник.Номенклатура], | $Тов.Артикул as Артикул, | $Тов.Рисунок as Рисунок, | $Тов.ТоварнаяГруппа as [ТоварнаяГруппа $Справочник.ТоварныеГруппы], -- ????? Если это справочник | Рег.Партии as Партия, | Рег.КоличествоОстаток as КонКол, | $Тов.КоэффПересчета as КоэфТук, |From | $РегистрОстатки.ОстаткиТоваров(:ДатаОтчета~,, " + ?(МестоХранения.Выбран()=0, "", "Рег.МестаХранения = :МестоХранения") + ") as Рег |Inner Join | $Справочник.Номенклатура Тов WITH (NOLOCK) ON Тов.ID = Рег.Номенклатура |where 1 = 1 |" + ?(ВыбТовары.РазмерСписка() > 0, "and Тов.ID in (Select Val From #СписокТоваров)", "")+ " |"; ЗапросДляТЗ.УстановитьТекстовыйПараметр("ДатаОтчета", ДатаОтчета); ЗапросДляТЗ.УстановитьТекстовыйПараметр("МестоХранения", МестоХранения); ЗапросДляТЗ.УложитьСписокОбъектов(ВыбТовары,"#СписокТоваров", "Номенклатура"); ТзЗапрос = ЗапросДляТЗ.ВыполнитьИнструкцию(ТекстЗапроса); Дальше по аналогии добавить условий |
|||
38
vladmenleo
03.10.23
✎
16:47
|
(34) Про оригинал согласен, но на прямой запрос переписать полчаса, ну час от силы. Зато потом на черные запросы смотреть не захочется
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |