Имя: Пароль:
1C
1С v8
Маленький вопрос по быстродействию.
,
0 ДенисЧ
 
16.11.11
16:06
Есть функция

&НаСервере
Функция НайтиПродукцию(Артикул, родитель)
   стрЗапрос =
   "ВЫБРАТЬ
   |    Номенклатура.Ссылка
   |ИЗ
   |    Справочник.Номенклатура КАК Номенклатура
   |ГДЕ
   |    Номенклатура.Артикул = &Артикул
   |    И Номенклатура.Ссылка В ИЕРАРХИИ(&_Родитель)";
   
   запрос = Новый Запрос;
   Запрос.Текст = стрЗапрос;
   Запрос.УстановитьПараметр("Артикул", Артикул);
   Запрос.УстановитьПараметр("_Родитель", родитель);
   рез = запрос.Выполнить();
   Если рез.Пустой() Тогда
       Возврат Справочники.Номенклатура.ПустаяСсылка();
   Иначе
       выб = рез.Выбрать();
       Если выб.Следующий() Тогда
           Возврат выб.Ссылка;
       Иначе
           Возврат Справочники.Номенклатура.ПустаяСсылка();
       КонецЕсли;
       
   КонецЕсли;
   
КонецФункции

Она вызывается ~1000 раз, занимает 13% времени работы обработки, но чаще всего ищет одну и ту же позицию. Если я результат буду кешировать в ТЗ (весь цикл идёт в НаСервере, так что ТЗ сохранится), не будет ли быстрее?
1 zak555
 
16.11.11
16:07
откуда вызывается НайтиПродукцию?
2 ДенисЧ
 
16.11.11
16:09
Из процедуры создания документа. А оная процедура - из цикла создания документов. Всё в одном серверном вызове.
Получить все артикулы сразу - лучше не предлагать. Там хитрая система с запросами к внешним базам, буду группировать - запутаюсь только.
3 Лефмихалыч
 
16.11.11
16:16
(0) быстрее будет. Я гарантирую это, ибо пробовал
4 Попытка1С
 
16.11.11
16:17
А в 8 нет параметризированных запросов? =)
5 Лефмихалыч
 
16.11.11
16:17
кстати, еще лучше ПЕРВЫЕ 1 всунуть в запрос. На всякий пожарный
6 Aleksey
 
16.11.11
16:18
Так вроде бы в 8.2 средствами 1С можно кэшировать. Т.е. если вызываются с теми же параметрами, то 1С берет из кэшаже
7 ДенисЧ
 
16.11.11
16:19
(3) с ТЗ быстрее? Попробую сейчас...
8 Aleksey
 
16.11.11
16:19
Там еще параметр есть "Повторное использование возвращаемых значений"
9 Ненавижу 1С
 
гуру
16.11.11
16:21
а не проще ли делать запрос не в цикле?
10 Stepa86
 
16.11.11
16:22
юзай кешируемые модули на сеанс или на вызов
11 ДенисЧ
 
16.11.11
16:23
(9) Не проще. Там сложная структура.
12 guitar_player
 
16.11.11
16:23
Иначе
           Возврат Справочники.Номенклатура.ПустаяСсылка();
       КонецЕсли;

вот это никогда не сработает
13 ДенисЧ
 
16.11.11
16:23
(8) Там это где?
(10) Это как?
14 ДенисЧ
 
16.11.11
16:23
(12) на всякий случай.
15 Fragster
 
гуру
16.11.11
16:24
да, я делал такое - норм кэшируется
16 Ненавижу 1С
 
гуру
16.11.11
16:24
(11) отмазки, гнилые
17 guitar_player
 
16.11.11
16:24
(14) галки у модулей есть
18 Stepa86
 
16.11.11
16:25
19 Fragster
 
гуру
16.11.11
16:25
(13)у общего модуля в 8.2 появились возможность
20 Лефмихалыч
 
16.11.11
16:27
(16) когда данные из семерки по оле и ты заранее не можешь сказать, какие именно данные из семерки понадобятся, хрен у тебя без цикла выйдет. Точнее выйдет, но тебе придется лишнее получать, а от этого скорость еще сильнее в жеппу уйдет
21 braynt
 
16.11.11
16:27
почему нельзя стандартными средствами?
справочники.Номенклатура.НайтиПоРеквизиту("Артикул",Артикул,Родитель);
22 laeg
 
16.11.11
16:28
(0) Артикула не уникальные ? Зависят от родителя ?
Если уникальные, то в качестве кэша можно использовать соответствие, есои конечно чаще всего ищется одна и тажа позиция.
23 Ненавижу 1С
 
гуру
16.11.11
16:28
(20) ну а так лишние не получаешь типа?
24 ДенисЧ
 
16.11.11
16:29
(22) Ага. Есть пересечение с разным смыслом.
(21) Что-то не взлетело, переписал так. А всё равно запрос к серверу будет оддин и тот же...
25 aleks-id
 
16.11.11
16:30
(24) в твоем случае (21) отработает быстрее запроса
26 aleks-id
 
16.11.11
16:31
+(25) давай сюда свой цикл
27 Лефмихалыч
 
16.11.11
16:31
(23) а так только то, что надо.
Не нуди. Чисто теоретически, да, можно обойтись без запроса в цикле, но на практике не всегда это нужно бывает. Если, к примеру задача одноразовая, то чем долбаться без цикла, проще закешировать в ТЗ, выполнить задачу и жить спокойно
28 Buster007
 
16.11.11
16:31
(20) когда я получаю данные из внешнего источника, я собираю в одно место всё то, что получил, а потом делаю 1 запрос.
А если делать в цикле, то конечно и в этом есть плюс... можно поиграть в пасьянс, например... ))
29 ДенисЧ
 
16.11.11
16:32
А, кеширование модуля... У меня пока всё во внешних обработках :-)
30 Ненавижу 1С
 
гуру
16.11.11
16:32
(27) не дал по нудеть...
просто у меня тож такого как в (0) масса найдется, вроде надо в запрос один, но... тут же рушится, например, парадигма повторного использования кода
31 Лефмихалыч
 
16.11.11
16:32
все теоретики могут идти с песнями прочь, я спорить не хочу, ибо мне похеру
32 ДенисЧ
 
16.11.11
16:33
(26) А зачем тебе мой цикл? :-) Он мне самому пригодится.
А сюда выкладывать этот *овнокод, почти прямую кальку с 77... Не...
33 Alexandr Puzakov
 
16.11.11
16:34
А нуна ли:

Номенклатура.Ссылка В ИЕРАРХИИ(&_Родитель)

Артикулы не уникальны? Это же приходится лопатить два индекса, если это условие убрать, то будет лопатиться только один...
34 ДенисЧ
 
16.11.11
16:35
(33) Про уникальность смотри выше.
35 aleks-id
 
16.11.11
16:35
(32)несцы. покоцай критические участки. но чтоб смысл понятен был !
36 Лефмихалыч
 
16.11.11
16:37
(35) данаиух. С ТЗ работать будет, как из пушки. Если это внешняя обработка, то ради нее кеширующий модуль создавать - из танка по воробьям. Так что ТЗ - самое простое и эффективное решение
37 aleks-id
 
16.11.11
16:38
(36) согласен. причем уверен, что данные из этой тз можно будет легко причпокнуть левым к тем данным, которые он перебирает в цикле, вместо того чтобы собрать один раз..
38 ДенисЧ
 
16.11.11
16:38
(35)
Для каждого стр из тзЗаявки Цикл
 док = СоздатьНайтиДок(стр.УникНомер);
 тзДанные1 = ПолучитьДанные(стр.УникНомер);
 Для каждого стр1 из тзДанные1 цикл
   тзПродукция = ПолучитьТзПродукции(стр1.ИдВидаПродукции);
   для каждого стр2 из тзПродукция Цикл
     стрДок = док.ТОвары.Добавить();
     ЗаполнитьСтрокуДок(стрДок);
   КонецЦикла;
 КонецЦикла;
КонецЦикла;

Это кратко :-) То есть структура продукции _там_ не такая, как в 1с. Там нет явных позиций, там есть совокупность признаков, размазанная по 4м таблицам... Мог бы мне оракл отдать дерево сразу, так не возился бы...
39 ДенисЧ
 
16.11.11
16:40
Ну вот, 2% выиграл... Дальше затыки идут уже на мелочах типа ссылка.ПолучитьОбъект(), спр.Записать() и проч.

Когда это всё заработает и время будет, соберу в более крупные запросы...
40 Alexandr Puzakov
 
16.11.11
16:41
А надо ли

Справочники.Номенклатура.ПустаяСсылка();

делать тыщу раз? Как-никак это обращение к глобальному контексту... Может лучше создать реквизит формы ссылающийся на справочник номенклатуры, обозвать его ПустаяНоменклатура и каждый раз возвращать его значение?
41 aleks-id
 
16.11.11
16:42
(38) ну и чо?
1. собирай ТЗ со строковыми данными (это будет твоя ТЧ документа). приспособь колонку под ИД документа.
2. забирай данные одним запросом к ТЗ
42 ДенисЧ
 
16.11.11
16:44
(40) Можно и так...
43 Alexandr Puzakov
 
16.11.11
16:44
Ну а самое главное:

&НаСервере

заменить на

&НаСервереБезКонтекста

В этой функции контекст формы нах не нужен.
44 braynt
 
16.11.11
16:44
Попробуй тзДанные1 поместить во временную таблицу и связать со справочником номенклатура по артиклу.
45 AlStorm
 
16.11.11
16:45
Соответствие быстрей ТЗ... Я за использование соответствия!
46 ДенисЧ
 
16.11.11
16:49
(43) Ага. А таблицу значений с формы я телепатически буду передавать?
47 aleks-id
 
16.11.11
16:50
(46) используй таб.часть обработки
48 Alexandr Puzakov
 
16.11.11
16:50
(46) в этой функции у тебя нет таблицы значений...
49 ДенисЧ
 
16.11.11
16:52
(48) тзЗаявки - это что?
(46) Как вариант... Не привык я к этим ещё :-) А в ней интерактивно галки можно расставлять? Расскрашивать там...
50 Alexandr Puzakov
 
16.11.11
16:54
И если уж так настойчиво охото побаловаться с универсальной коллекцией, то гораздо целесообразнее будет использовать Соответствие...
51 aleks-id
 
16.11.11
16:54
(49) нет предела совершенству ;)
52 Alexandr Puzakov
 
16.11.11
17:01
Глаза прям режет... А нельзя ли переписать код хотя бы вот так:

Для каждого СтрокаЗаявки из ТаблицаЗаявок Цикл
 Документ = СоздатьНайтиДокументЗаявки(СтрокаЗаявки.УникНомер);
 ТаблицаДанных = ПолучитьДанные(СтрокаЗаявки.УникНомер);
 Для каждого СтрокаДанные из ТаблицаДанных цикл
   ТаблицаПродукции = ПолучитьТаблицуПродукции(СтрокаДанные.ИдВидаПродукции);
   для каждого СтрокаПродукция из ТаблицаПродукции Цикл
     НовыйТовар = Документ.Товары.Добавить();
     ЗаполнитьСтрокуТовара(НовыйТовар);
   КонецЦикла;
 КонецЦикла;
КонецЦикла;

?
53 ДенисЧ
 
16.11.11
17:02
(52) там псевдокод. На самам деле всё ещё хуже...
54 Alexandr Puzakov
 
16.11.11
17:04
(53) а чо так?
55 ДенисЧ
 
16.11.11
17:07
(54) Некогда мне картины сейчас рисовать. Нужно как можно быстрее перенести всё это 8ку, потом уже вылизывать буду. Поэтому идёт почти тупое калькирование.
56 Фокусник
 
16.11.11
17:15
(0) Может лучше не в ТЗ кешировать, а в структуре? Например ключ для структуры: Артикул_КодРодителя. Если не нашлось в кеше, то уже делать запрос.
57 ДенисЧ
 
16.11.11
17:21
(56) По советам выше переделал в соответствие.
58 Ненавижу 1С
 
гуру
16.11.11
17:22
(31) я уже понял ))