Имя: Пароль:
1C
1С v8
Быстродействие 1С
,
0 Baglandir
 
11.10.12
19:03
В докуменете реализация товаров и услуг есть вот такая строка при записи (как я понимаю типовая)

Если мУдалятьДвижения Тогда
       ОбщегоНазначения.УдалитьДвиженияРегистратора(ЭтотОбъект, Отказ);
КонецЕсли;

Процедура УдалитьДвиженияРегистратора(ДокументОбъект, Отказ) Экспорт
   
   // получение списка регистров, по которым существуют движения
   ТаблицаДвижений = ПолныеПрава.ОпределитьНаличиеДвиженийПоРегистратору(ДокументОбъект.Ссылка);
   ТаблицаДвижений.Колонки.Добавить("НаборЗаписей");
   ТаблицаДвижений.Колонки.Добавить("БезусловноеУдаление", Новый ОписаниеТипов("Булево"));
       
   Для Каждого СтрокаДвижения ИЗ ТаблицаДвижений Цикл
       // имя регистра передается как значение, полученное с помощью
       // функции ПолноеИмя() метаданных регистра
       ПозицияТочки = Найти(СтрокаДвижения.Имя, ".");
       ТипРегистра = Лев(СтрокаДвижения.Имя, ПозицияТочки - 1);
       ИмяРегистра = СокрП(Сред(СтрокаДвижения.Имя, ПозицияТочки + 1));
       
       ЕСли ТипРегистра = "РегистрНакопления" Тогда
           МетаданныеНабора = Метаданные.РегистрыНакопления[ИмяРегистра];
           Набор = РегистрыНакопления[ИмяРегистра].СоздатьНаборЗаписей();
           
       ИначеЕсли ТипРегистра = "РегистрБухгалтерии" Тогда
           МетаданныеНабора = Метаданные.РегистрыБухгалтерии[ИмяРегистра];
           Набор = РегистрыБухгалтерии[ИмяРегистра].СоздатьНаборЗаписей();
           
       ИначеЕсли ТипРегистра = "РегистрСведений" Тогда
           МетаданныеНабора = Метаданные.РегистрыСведений[ИмяРегистра];
           Набор = РегистрыСведений[ИмяРегистра].СоздатьНаборЗаписей();
           
       ИначеЕсли ТипРегистра = "РегистрРасчета" Тогда
           МетаданныеНабора = Метаданные.РегистрыРасчета[ИмяРегистра];
           Набор = РегистрыРасчета[ИмяРегистра].СоздатьНаборЗаписей();
           
       КонецЕсли;
           
       Если НЕ ПравоДоступа("Изменение", МетаданныеНабора) Тогда
           // отсутствуют права на всю таблицу регистра
           СообщитьОбОшибке("Нарушение прав доступа", Отказ, СтрокаДвижения.Имя);
           Возврат;
       КонецЕсли;
           
       Набор.Отбор.Регистратор.Установить(ДокументОбъект.Ссылка);
       // набор не записывается сразу, чтобы не откатывать транзакцию, если впоследствии
       // выяснится, что на один из регистров не хватает прав.
       СтрокаДвижения.НаборЗаписей = Набор;
       
   КонецЦикла;
   
   Для Каждого СтрокаДвижения ИЗ ТаблицаДвижений Цикл
       Если СтрокаДвижения.БезусловноеУдаление Тогда
           ПолныеПрава.ЗаписатьНаборЗаписейНаСервере(СтрокаДвижения.НаборЗаписей, ДокументОбъект.Ссылка);
       Иначе
           Попытка
               СтрокаДвижения.НаборЗаписей.Записать();
           Исключение
               // возможно «сработал» RLS или механизм даты запрета изменения
               СообщитьОбОшибке(ОписаниеОшибки(), Отказ, СтрокаДвижения.Имя);
               ВызватьИсключение "Операция не выполнена";
           КонецПопытки;
       КонецЕсли;
   КонецЦикла;
   
   ОчисткаКоллекцииДвиженийДокумента(ДокументОбъект);
   
   // Удаление записей регистрации из всех последовательностей
   УдалитьРегистрациюДокументаВПоследовательностях(ДокументОбъект, Истина);

КонецПроцедуры




Изза нее документ проводится 60-80 секунд, отменяется тоже.

Как можно ее оптимизировать или ускорить 1С ?
1 Ardi
 
11.10.12
19:05
Какая длинная строка. Тысяч на 50 символов.
2 ДенисЧ
 
11.10.12
19:09
Это точно строка? :-)
3 Fragster
 
гуру
11.10.12
19:09
у меня такая функция делается за .5 секунд
4 Demiurg
 
11.10.12
19:09
http://gilev.blogspot.com/2012/09/1.html замерь и покажи план запроса
60 секунд - либо у тебя табличная часть десятки тысяч строк (большие объемы) либо блокировки (но тогда монопльно должно быстро работать), либо план запроса смотреть, где там оптимизатор ошибается
5 Fragster
 
гуру
11.10.12
19:10
(4) он на ноутбуке работает просто в 100500ром
6 Demiurg
 
11.10.12
19:11
(5) явных ошибок не вижу, поэтому надо смотреть план запроса
7 ILM
 
гуру
11.10.12
19:15
РЛС включен? Ограничение по складам?
8 Baglandir
 
11.10.12
19:35
(7) да
9 Baglandir
 
11.10.12
19:35
именно на подчиненной базе Риб на складе
10 ILM
 
гуру
11.10.12
19:38
Попробуй без РЛС скорость замерить?
11 ILM
 
гуру
11.10.12
19:38
Дай юзеру доступность складов без РЛС.
12 Baglandir
 
11.10.12
19:40
Возможно вопрос глупый но как отключить рлс?
13 Snovy
 
11.10.12
19:50
(10)-(12) Весь основной код выполняется в модуле ПолныеПрава, а он привилегированный. Так что ИМХО РЛС тут ни при чем.
14 Fragster
 
гуру
11.10.12
19:55
СтрокаДвижения.БезусловноеУдаление = Истина, не?
15 ILM
 
гуру
11.10.12
20:24
(13) Удивительно, но факт.
16 Baglandir
 
12.10.12
10:40
Плужит очень сильно здесь
Для Каждого СтрокаДвижения ИЗ ТаблицаДвижений Цикл
       Если СтрокаДвижения.БезусловноеУдаление Тогда
           ПолныеПрава.ЗаписатьНаборЗаписейНаСервере(СтрокаДвижения.НаборЗаписей, ДокументОбъект.Ссылка);
       Иначе
           Попытка
// Тут дольше всего плужит
               СтрокаДвижения.НаборЗаписей.Записать();
           Исключение
               // возможно «сработал» RLS или механизм даты запрета изменения
               СообщитьОбОшибке(ОписаниеОшибки(), Отказ, СтрокаДвижения.Имя);
               ВызватьИсключение "Операция не выполнена";
           КонецПопытки;
       КонецЕсли;
   КонецЦикла;
17 Baglandir
 
12.10.12
10:41
И тут

Процедура УдалитьДвиженияРегистратора(ДокументОбъект, Отказ) Экспорт
   
   // вот тут !!!
   ТаблицаДвижений = ПолныеПрава.ОпределитьНаличиеДвиженийПоРегистратору(ДокументОбъект.Ссылка);
18 Baglandir
 
12.10.12
10:41
вот текст функции

Функция ОпределитьНаличиеДвиженийПоРегистратору(ДокументСсылка) Экспорт
   ТекстЗапроса = "";    
   // для исключения падения для документов, проводящимся более чем по 256 таблицам
   счетчик_таблиц = 0;
   
   МетаданнныеДокумента = ДокументСсылка.Метаданные();
   
   Если МетаданнныеДокумента.Движения.Количество() = 0 Тогда
       Возврат Новый ТаблицаЗначений;
   КонецЕсли;
   
   Для Каждого Движение ИЗ МетаданнныеДокумента.Движения Цикл
       // в запросе получаем имена регистров, по которым есть хотя бы одно движение
       // например,
       // ВЫБРАТЬ Первые 1 «РегистрНакопления.ТоварыНаСкладах»
       // ИЗ РегистрНакопления.ТоварыНаСкладах
       // ГДЕ Регистратор = &Регистратор
       
       // имя регистра приводим к Строка(200), см. ниже
       ТекстЗапроса = ТекстЗапроса + "
       |" + ?(ТекстЗапроса = "", "", "ОБЪЕДИНИТЬ ВСЕ ") + "
       |ВЫБРАТЬ ПЕРВЫЕ 1 ВЫРАЗИТЬ(""" + Движение.ПолноеИмя()
       +  """ КАК Строка(200)) КАК Имя ИЗ " + Движение.ПолноеИмя()
       + " ГДЕ Регистратор = &Регистратор";
       
       // если в запрос попадает более 256 таблиц – разбиваем его на две части
       // (вариант документа с проведением по 512 регистрам считаем нежизненным)
       счетчик_таблиц = счетчик_таблиц + 1;
       Если счетчик_таблиц = 256 Тогда
           Прервать;
       КонецЕсли;
       
   КонецЦикла;
   
   Запрос = Новый Запрос(ТекстЗапроса);
   ЗАпрос.УстановитьПараметр("Регистратор", ДокументСсылка);
   // при выгрузке для колонки «Имя» тип устанавливается по самой длинной строке из запроса
   // при втором проходе по таблице новое имя может не «влезть», по этому сразу в запросе
   // приводится к строка(200)
   ТаблицаЗапроса = Запрос.Выполнить().Выгрузить();
   
   // если количество таблиц не превысило 256 – возвращаем таблицу
   Если счетчик_таблиц = МетаданнныеДокумента.Движения.Количество() Тогда
       Возврат ТаблицаЗапроса;            
   КонецЕсли;
   
   // таблиц больше чем 256, делаем доп. запрос и дополняем строки таблицы.
   
   ТекстЗапроса = "";
   Для Каждого Движение ИЗ МетаданнныеДокумента.Движения Цикл
       
       Если счетчик_таблиц > 0 Тогда
           счетчик_таблиц = счетчик_таблиц - 1;
           Продолжить;
       КонецЕсли;
       
       ТекстЗапроса = ТекстЗапроса + "
       |" + ?(ТекстЗапроса = "", "", "ОБЪЕДИНИТЬ ВСЕ ") + "
       |ВЫБРАТЬ ПЕРВЫЕ 1 """ + Движение.ПолноеИмя() +  """ КАК Имя ИЗ "
       + Движение.ПолноеИмя() + " ГДЕ Регистратор = &Регистратор";    
       
       
   КонецЦикла;
   Запрос.Текст = ТекстЗапроса;
   Выборка = Запрос.Выполнить().Выбрать();
   Пока Выборка.Следующий() Цикл
       СтрокаТаблицы = ТаблицаЗапроса.Добавить();
       ЗаполнитьЗначенияСвойств(СтрокаТаблицы, Выборка);
   КонецЦикла;
   
   Возврат ТаблицаЗапроса;
19 МуМу
 
12.10.12
10:47
(18) Интересно кто писал сей шедевр? Можно ведь один раз статически получить для каждого документа список возможных регистраторов. Кроме того можно при проведение заполнить эти значения. В любом случае криво реализовано.
20 Baglandir
 
12.10.12
10:49
Писали - до меня , время проведения данного куска "60- 150" секунд на компе за 4500 грн
10-20 на компе за 4500 УЕ
21 Baglandir
 
12.10.12
10:50
(19)

По моему это типовый механизм
22 Baglandir
 
12.10.12
10:53
(14) Не - БезусловноеУдаление ложь
23 Baglandir
 
12.10.12
10:54
(19)  А можно чуть подробней , как именно получить "Можно ведь один раз статически получить для каждого документа список возможных регистраторов" и  можно при проведение заполнить эти значения" ?
24 Fragster
 
гуру
12.10.12
10:55
(22) говорю в цикл добавления строк и создания наборов добавь строку...
25 МуМу
 
12.10.12
11:02
(23) У тебя таблиц больше чем 256?
26 МуМу
 
12.10.12
11:04
Также скажи какая версия MSSQL у тебя?
27 Baglandir
 
12.10.12
11:06
(26)2008 ентерпрайз
Та не,где то  15 таблиц
28 Baglandir
 
12.10.12
11:21
Зачем вообще эта процедура ?, Сижу не могу понять, она вроде - удаляет движения и все, так такая функция есть в самом документе
29 Baglandir
 
12.10.12
11:24
(24) Поставил - полезли ошибки кода.
30 МуМу
 
12.10.12
11:24
(28)Получаются имена регистров по которым есть хотя бы одно движение. А потом видимо проверяются права на удаление.
31 Fragster
 
гуру
12.10.12
11:27
(29) ты такой загадочный.... какие ошибки?
32 Fragster
 
гуру
12.10.12
11:28
просто в регистрах автоматическое удаление выключено
33 МуМу
 
12.10.12
11:29
ТекстЗапроса = ТекстЗапроса + "
       |" + ?(ТекстЗапроса = "", "", "ОБЪЕДИНИТЬ ВСЕ ") + "
       |ВЫБРАТЬ ПЕРВЫЕ 1 ВЫРАЗИТЬ(""" + Движение.ПолноеИмя()
       +  """ КАК Строка(200)) КАК Имя ИЗ " + Движение.ПолноеИмя()
       + " ГДЕ Регистратор = &Регистратор";

Вот это выполни отдельно для каждого регистра по отдельности.
34 МуМу
 
12.10.12
11:30
Топ 1 конечно долна быстро отрабатывать но возможны ньюансы. Да и вообще ты так и не назвал из отладчика строку кода где тормозит. Я имею ввиду в самой процедуре.
35 МуМу
 
12.10.12
11:32
Если тормозит на каком то регистре то можно будет указать явную сортировку в топ 1. В этом случае сюрпризов быть не должно.
36 Fragster
 
гуру
12.10.12
11:33
(34) тормозит СтрокаДвижения.НаборЗаписей.Записать(); инфа 100%
37 МуМу
 
12.10.12
11:46
(36) Если так, то тогда смотрим дефрагментацию индексов и выполняем переиндексацию. Такж обращаем внимание на дисковуб подсистему. А вообще какое то гадание на кофейной гуще. "Имя сестра, имя"(д'артаньян):)  Вообщем (0) должен назвать конкретную строку кода , после этого можно будет думать.
38 Fragster
 
гуру
12.10.12
11:47
(37) RLS же срабатывает... надо сделать так, чтобы набор записывался в модуле с полными правами
39 aspirant
 
12.10.12
11:47
(36) ну она у всех тормозит...
40 Baglandir
 
12.10.12
11:50
Включил увтоматическое удаление движений, и закоментил данные процедуры
Отмена проведение 3-5 секунд , Проведение 10 - 15  Жесть

Я так понимаю в типовых данная штука для РЛС предназначена?
41 ДенисЧ
 
12.10.12
11:51
(36) Неа... Почти треть времени занимает именно выборка топ 1 по регистратору в большом регистре... Инфа 146%. У меня, по крайней мере.
42 Fragster
 
гуру
12.10.12
11:55
(41) у тебя там чота с дисками, мы это уже выяснили
43 Fragster
 
гуру
12.10.12
11:56
(42)+ или оперативы не хватает, или индексы необслужены
44 МуМу
 
12.10.12
12:02
(41)Разумеется проведи переиндекссацию. А потом попробуй указать явно сортировку(сортировать по) по какому нибудь самому по размерам маленькому индексу(желательно селктивному) По умолчанию берется кластерный(это нормальный вариант но бывают ньюансы)
45 Artful Den
 
12.10.12
12:17
(36) таже самая проблема с УПП, SQL. Переиндексацию делали, бесполезно.

Так кто-нибудь поборол эту проблему?
46 Fragster
 
гуру
12.10.12
12:18
(45) если RLS, то (14)
47 Artful Den
 
12.10.12
12:20
(46) RLS не используем
48 Baglandir
 
12.10.12
12:59
Может ли толмозить база изза размера ? у меня размер базы 37 гигабайт
49 Baglandir
 
12.10.12
13:34
Продолжение. Почистил все програмные заморочки Осталась голая запись документа, Если быть точным (отмена проведения)

в главной базе делается по 3-5 секунды до оптимизации 10 -15
В складской - 80 секунд после оптимизации до  210 - 250.

Но это всеравно долго очень
Вопрос  у меня в складской базе находятся не только документы по складу но и документы (реализации товаров и услуг) по другим складам

До падения базы были только по данному складу. Может ли тормозить изза этого ?

и

У меня в базе склада давно не делались тех работы (реиндексация и тп )
Влияет ли это на быстродействие ?


Ну и понятно на SQl тоже обслуживание давно не делал.

Влияет ли это ?

+ У меня в базе есть регист "Версионирование данных на 18 гиг"
50 Fragster
 
гуру
12.10.12
13:38
так тормозить стало после падения базы?
51 Baglandir
 
12.10.12
13:52
ага , база упала , я копию реальной базы розвернул