Очень медленый перенос данных из *.DBF в операции
17.06.2008
08:23
#1
"стоит задача переноса данных из файла *.DBF и на основе этих данных создания операций.
сам файл DBF весит 30 мб.
код примерно следующий
------------
СпрКВ=СоздатьОбъект("Справочник.Квартиры");
ФайлКВ=СоздатьОбъект("XBASE");
ФайлКВ.ОткрытьФайл(СокрЛП(ФайлСДанными));
ФайлКВ.КодоваяСтраница(1);
Если ФайлКВ.Открыта()=0 Тогда
Сообщить("Выберите путь к данным!!!");
Возврат ;
КонецЕсли;
//УстановитьТипВеличины();
БухИт = СоздатьОбъект("БухгалтерскиеИтоги");
ФайлКВ.Первая();
СпрКВ.ИспользоватьДату(ТекущаяДата());
Пока (ФайлКВ.ВКонце()=0) Цикл
Если СпрКВ.НайтиПоКоду(ФайлКВ.SS,0)=1 Тогда
Опер=СоздатьОбъект("Операция");
Опер.Новая();
Опер.Содержание="ул. "+СпрКВ.ТекущийЭлемент().Владелец.Владелец.Наименование+" д."+СпрКВ.ТекущийЭлемент().Владелец.Наименование+" "+"кв."+СпрКВ.ТекущийЭлемент().Наименование;
Опер.ДатаОперации=Дата("31.12.2007");
Опер.НоваяПроводка();
Опер.Кредит.Счет = СчетПоКоду("1.4");
Опер.Кредит.Субконто(1, СпрКВ.ТекущийЭлемент());
Опер.Сумма = ФайлКВ.SAL1;
Опер.СодержаниеПроводки = "Сальдо на начало года "+СпрКВ.ТекущийЭлемент().полноеНаименование();
Опер.Записать();
--------------------------------
ВОБЩЕМ на каждый месяц создается новая операция и в каждой операции 5-7 проводок .
Вопрос в следующем что именно тормозит процесс? Загрузка процессора 3% !! Всего остального тоже предостаточно.
"
сам файл DBF весит 30 мб.
код примерно следующий
------------
СпрКВ=СоздатьОбъект("Справочник.Квартиры");
ФайлКВ=СоздатьОбъект("XBASE");
ФайлКВ.ОткрытьФайл(СокрЛП(ФайлСДанными));
ФайлКВ.КодоваяСтраница(1);
Если ФайлКВ.Открыта()=0 Тогда
Сообщить("Выберите путь к данным!!!");
Возврат ;
КонецЕсли;
//УстановитьТипВеличины();
БухИт = СоздатьОбъект("БухгалтерскиеИтоги");
ФайлКВ.Первая();
СпрКВ.ИспользоватьДату(ТекущаяДата());
Пока (ФайлКВ.ВКонце()=0) Цикл
Если СпрКВ.НайтиПоКоду(ФайлКВ.SS,0)=1 Тогда
Опер=СоздатьОбъект("Операция");
Опер.Новая();
Опер.Содержание="ул. "+СпрКВ.ТекущийЭлемент().Владелец.Владелец.Наименование+" д."+СпрКВ.ТекущийЭлемент().Владелец.Наименование+" "+"кв."+СпрКВ.ТекущийЭлемент().Наименование;
Опер.ДатаОперации=Дата("31.12.2007");
Опер.НоваяПроводка();
Опер.Кредит.Счет = СчетПоКоду("1.4");
Опер.Кредит.Субконто(1, СпрКВ.ТекущийЭлемент());
Опер.Сумма = ФайлКВ.SAL1;
Опер.СодержаниеПроводки = "Сальдо на начало года "+СпрКВ.ТекущийЭлемент().полноеНаименование();
Опер.Записать();
--------------------------------
ВОБЩЕМ на каждый месяц создается новая операция и в каждой операции 5-7 проводок .
Вопрос в следующем что именно тормозит процесс? Загрузка процессора 3% !! Всего остального тоже предостаточно.
"
17.06.2008
09:29
#2
"оптимизируй алгоритм, как минимум. убери лишние ненужные разыменования ссылок, примени транзакции... вот так, примерно:
СпрКВ=СоздатьОбъект("Справочник.Квартиры");
ФайлКВ=СоздатьОбъект("XBASE");
ФайлКВ.ОткрытьФайл(СокрЛП(ФайлСДанными));
ФайлКВ.КодоваяСтраница(1);
Если ФайлКВ.Открыта()=0 Тогда
Сообщить("Выберите путь к данным!!!");
Возврат ;
КонецЕсли;
Опер=СоздатьОбъект("Операция");
НужнаяДата=Дата("31.12.2007");
Сч1_4=СчетПоКоду("1.4");
Счетчик=0;
НачатьТранзакцию();
ФайлКВ.Первая();
Пока (ФайлКВ.ВКонце()=0) Цикл
Если СпрКВ.НайтиПоКоду(ФайлКВ.SS,0)=1 Тогда
ТекущаяКвартира=СпрКВ.ТекущийЭлемент();
Опер.Новая();
Опер.Содержание="ул. "+ТекущаяКвартира.Владелец.Владелец.Наименование+" д."+ТекущаяКвартира.Владелец.Наименование+" "+"кв."+ТекущаяКвартира.Наименование;
Опер.ДатаОперации=НужнаяДата;
Опер.НоваяПроводка();
Опер.Кредит.Счет = Сч1_4;
Опер.Кредит.Субконто(1, ТекущаяКвартира);
Опер.Сумма = ФайлКВ.SAL1;
Опер.СодержаниеПроводки = "Сальдо на начало года "+ТекущаяКвартира.ПолноеНаименование;
Опер.Записать();
КонецЕсли;
Счетчик=Счетчик+1;
Если Счетчик>100 Тогда
НачатьТранзакцию();
ЗафиксироватьТранзакцию();
Счетчик=0;
КонецЕсли;
КонецЦикла;
ЗафиксироватьТранзакцию();
p.s. странный алгоритм, на каждую квартиру создается новая операция с одной проводкой (а не 5-7), не проверяется, а была ли она уже создана ранее, а нет ли в ней уже нужных проводок, в общем, над этим тоже подумайте. При сложении строк, наверное, еще бы пробелы по бокам пооткусывать"
СпрКВ=СоздатьОбъект("Справочник.Квартиры");
ФайлКВ=СоздатьОбъект("XBASE");
ФайлКВ.ОткрытьФайл(СокрЛП(ФайлСДанными));
ФайлКВ.КодоваяСтраница(1);
Если ФайлКВ.Открыта()=0 Тогда
Сообщить("Выберите путь к данным!!!");
Возврат ;
КонецЕсли;
Опер=СоздатьОбъект("Операция");
НужнаяДата=Дата("31.12.2007");
Сч1_4=СчетПоКоду("1.4");
Счетчик=0;
НачатьТранзакцию();
ФайлКВ.Первая();
Пока (ФайлКВ.ВКонце()=0) Цикл
Если СпрКВ.НайтиПоКоду(ФайлКВ.SS,0)=1 Тогда
ТекущаяКвартира=СпрКВ.ТекущийЭлемент();
Опер.Новая();
Опер.Содержание="ул. "+ТекущаяКвартира.Владелец.Владелец.Наименование+" д."+ТекущаяКвартира.Владелец.Наименование+" "+"кв."+ТекущаяКвартира.Наименование;
Опер.ДатаОперации=НужнаяДата;
Опер.НоваяПроводка();
Опер.Кредит.Счет = Сч1_4;
Опер.Кредит.Субконто(1, ТекущаяКвартира);
Опер.Сумма = ФайлКВ.SAL1;
Опер.СодержаниеПроводки = "Сальдо на начало года "+ТекущаяКвартира.ПолноеНаименование;
Опер.Записать();
КонецЕсли;
Счетчик=Счетчик+1;
Если Счетчик>100 Тогда
НачатьТранзакцию();
ЗафиксироватьТранзакцию();
Счетчик=0;
КонецЕсли;
КонецЦикла;
ЗафиксироватьТранзакцию();
p.s. странный алгоритм, на каждую квартиру создается новая операция с одной проводкой (а не 5-7), не проверяется, а была ли она уже создана ранее, а нет ли в ней уже нужных проводок, в общем, над этим тоже подумайте. При сложении строк, наверное, еще бы пробелы по бокам пооткусывать"
17.06.2008
10:03
#3
Спасибо большое за ответ!
по поводу кода не много не так, я просто опустил оставшиеся 5-6 проводок . Проверка убрана сознательно, т.к. это разовое действие и перед ним база отчищаеться вообще от всего, Хотя сейчас подумал, логика то есть в проверке, я же могу остановить перенос данных и что-бы возобновить мне придеться опять заняться чисткой((
по ссылкам согласен, тем более у меня и обращений к счету и к ул. "+ТекущаяКвартира.Владелец.Владелец.Наименование+" д."+ТекущаяКвартира.Владелец.Наименование+" "+"кв."+ТекущаяКвартира.Наименование несколько раз за цикл
Почитал про Транзакцию, думал она только отвечает за целостность данных, ан нет, буду пробовать!
Блин? я наверное зря после каждой проводки ставлю Опер.Записать()?
по поводу кода не много не так, я просто опустил оставшиеся 5-6 проводок . Проверка убрана сознательно, т.к. это разовое действие и перед ним база отчищаеться вообще от всего, Хотя сейчас подумал, логика то есть в проверке, я же могу остановить перенос данных и что-бы возобновить мне придеться опять заняться чисткой((
по ссылкам согласен, тем более у меня и обращений к счету и к ул. "+ТекущаяКвартира.Владелец.Владелец.Наименование+" д."+ТекущаяКвартира.Владелец.Наименование+" "+"кв."+ТекущаяКвартира.Наименование несколько раз за цикл
Почитал про Транзакцию, думал она только отвечает за целостность данных, ан нет, буду пробовать!
Блин? я наверное зря после каждой проводки ставлю Опер.Записать()?
17.06.2008
10:58
#4
Ну... транзакция, в принципе, штука, которая убивает двух зайцев.
1. Если что то не получится, то в базе не появится кривой результат.
2. При объявлении транзакции дальнейшая работа идет в памяти, и не идет обновление базы данных на жестком диске. Соответственно, скорости выше на порядки. Но! Если памяти мало, а задача по изменению в базе данных огромна, то операционка начнет делать swap, поэтому, если я полностью уверен в алгоритме и "кривой" результат не ожидаю, то периодически по счетчику фиксирую транзакцию, высвобождая память.
Опер.Записать(), кнечно не надо делать после каждой проводки. Ведь при этом пересчитываются бух.итоги, а это небыстро. Накидали в операцию все нужные проводки, потом записали. Ну и со строкой, тоже, посчитать ее как то надо только один раз. Хотя... складывание строк идет быстро, а вот сравнение строк, если оно будет, идет гораздо дольше.
1. Если что то не получится, то в базе не появится кривой результат.
2. При объявлении транзакции дальнейшая работа идет в памяти, и не идет обновление базы данных на жестком диске. Соответственно, скорости выше на порядки. Но! Если памяти мало, а задача по изменению в базе данных огромна, то операционка начнет делать swap, поэтому, если я полностью уверен в алгоритме и "кривой" результат не ожидаю, то периодически по счетчику фиксирую транзакцию, высвобождая память.
Опер.Записать(), кнечно не надо делать после каждой проводки. Ведь при этом пересчитываются бух.итоги, а это небыстро. Накидали в операцию все нужные проводки, потом записали. Ну и со строкой, тоже, посчитать ее как то надо только один раз. Хотя... складывание строк идет быстро, а вот сравнение строк, если оно будет, идет гораздо дольше.
Читают тему
(гостей: 1)