Имя: Пароль:
1C
 
Хочу сохранить текстовый файл в БД - есть возможность сделать это быстрее?
0 RomaH
 
naïve
20.05.15
13:32
Про хранение файлов вне БД - знаю и понимаю

но вопрос - есть возможность сделать сохранение в ХЗ быстрее?

текст - общий объем 25 метров (900 000 строк)
храню в документе в виде ХЗ
отображаю в ТекстовомДокументе - реквизит формы

сохраняю так:

&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
    
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
    
    ТекстРеестра.Записать(ИмяВременногоФайла);
    
    ДвоичныеДанные = Новый ДвоичныеДанные(ИмяВременногоФайла);
    ТекущийОбъект.ТекстФайлаРеестра = Новый ХранилищеЗначения(ДвоичныеДанные,Новый СжатиеДанных(9));
    
//Ну или так - по времени одинаково
    //ТекущийОбъект.ТекстФайлаРеестра = Новый ХранилищеЗначения(ТекстРеестра,Новый СжатиеДанных(6));
КонецПроцедуры

занимает более 5 минут
есть варианты?
1 Волшебник
 
модератор
20.05.15
13:33
отключи сжатие
2 aka AMIGO
 
20.05.15
13:34
(0) можно в БД хранить ссылку, а не документ
3 RomaH
 
naïve
20.05.15
13:35
(1) не помогает - "секундомер включается" после выхода из процедуры
т.е. весь код внутри процедуры отрабатывает быстро - секунд 5 где-то
4 RomaH
 
naïve
20.05.15
13:36
(2) еще раз - я знаю что можно хранить ссылку на файл
но вот так звезды встали - хочу хранить в базе
5 Fragster
 
гуру
20.05.15
13:37
а нафиг там временный файл?
6 Fragster
 
гуру
20.05.15
13:38
какая строка в замере занимает столько времени?
7 sapphire
 
20.05.15
13:40
(5) +1
8 Fragster
 
гуру
20.05.15
13:44
есть мнение, что с клиента надо убрать реквизит объекта с данными нафиг
9 RomaH
 
naïve
20.05.15
13:48
(5) просто так - эксперименты

ТекущийОбъект.ТекстФайлаРеестра = Новый ХранилищеЗначения(ТекстРеестра);

по времени - тоже самое

никакая - выход из процедуры - и жду пока сохранит

(8) чего убрать? - на клиенте форма с реквизитом ФОРМЫ типа ТекстовыйДокумент - с именем "ТекстРеестра"
10 RomaH
 
naïve
20.05.15
13:49
(6) никакая - выход из процедуры - и жду пока сохранит
11 Fragster
 
гуру
20.05.15
14:01
(10) т.е. все дело в сериализации этого дела для передачи клиент-сервер. т.е. см (8), а там уже нужно придумывать, как работать с этим документом без передачи его в контексте туда-сюда
12 DmitrO
 
20.05.15
14:03
(11)да нет же, все уже на сервере, дело в самой записи в базу похоже
13 Fragster
 
гуру
20.05.15
14:09
(12) нет, дело в передаче контекста на клиент и обратно
14 Fragster
 
гуру
20.05.15
14:10
для проверки можешь во внешней обработке в серверной процедуре прочитать и записать документ, не передавая его на клиент ни в каком виде
15 DmitrO
 
20.05.15
14:13
(13)может быть, это смотря как автор определяет что запись завершилась, в объекте в ПриЗаписи надо точку поставить, посмотреть где она в этих 5ти минутах сработает
16 RomaH
 
naïve
20.05.15
14:15
(13) вопрос тогда - как этого избежать?
17 RomaH
 
naïve
20.05.15
14:17
не менять текущийобъект - а писать в отдельный объект конфигурации?
18 RomaH
 
naïve
20.05.15
14:28
ага - (13) похоже начинаю понимать
убрал тело процедуры "ПередЗаписьюНаСервере"
сделал "ПриЗаписиНаСервере"

он у меня пока не вошел в ПриЗаписиНаСервере

т.е. надо с клиента вызвать сервер без контекста передав в него временное хранилище?

т.е. не должно быть
&НаСервере
Процедура
- ибо в этом случае у меня гоняется весь "ТекстРеестра" на сервер и обратно ... хотя внутри "перед записью" заходит быстро
19 RomaH
 
naïve
20.05.15
14:30
&НаСервере
Процедура

заходит быстро

КонецПроцедуры
а выходит - медленно
т.е. контекст передается обратно
почему он передается обратно - если с ним ничего не далали?
20 RomaH
 
naïve
20.05.15
14:48
т.е. получается - перед любым серверным вызовом с контекстом - надо очистить ТекстРеестра


&НаСервереБезКонтекста
Функция ПолучитьТекстИзДокумента(Знач ОбъектСсылка)
    
    МенеджерЗаписи = РегистрыСведений.МЭК_ФайлыРеестров.СоздатьМенеджерЗаписи();
    
    МенеджерЗаписи.ДокументРеестра = ОбъектСсылка;
    
    МенеджерЗаписи.Прочитать();
    
    ДвоичныеДанные = МенеджерЗаписи.ТелоРеестра.Получить();
    
    АдресВременногоХранилища = ПоместитьВоВременноеХранилище(ДвоичныеДанные);
    
    Возврат АдресВременногоХранилища;
    
КонецФункции

&НаКлиенте
Процедура КомандаПоказатьТекстФайла(Команда)
    
    Если ТекстРеестра.КоличествоСтрок() = 0 Тогда
        
        АВХ = ПолучитьТекстИзДокумента(Объект.Ссылка);
        ДвоичныеДанные = ПолучитьИзВременногоХранилища(АВХ);
        
        ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xml");
        ДвоичныеДанные.Записать(ИмяВременногоФайла);
    
        ТекстРеестра.Прочитать(ИмяВременногоФайла,Неопределено);

    КонецЕсли;
    
КонецПроцедуры

&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
    
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
    
    ТекстРеестра.Записать(ИмяВременногоФайла);
    ТекстРеестра.Очистить(); //самое главное
    
    ДвоичныеДанные = Новый ДвоичныеДанные(ИмяВременногоФайла);
    
    АВХ = ПоместитьВоВременноеХранилище(ДвоичныеДанные);
    
    ПередЗаписьюНаСервере(АВХ,Объект.Ссылка);
    
КонецПроцедуры

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


т.е. принцип такой?
21 RomaH
 
naïve
20.05.15
15:01
в итоге:

&НаСервереБезКонтекста
Функция ПолучитьТекстИзДокумента(Знач ОбъектСсылка)
    
    МенеджерЗаписи = РегистрыСведений.МЭК_ФайлыРеестров.СоздатьМенеджерЗаписи();
    
    МенеджерЗаписи.ДокументРеестра = ОбъектСсылка;
    
    МенеджерЗаписи.Прочитать();
    
    ТекстовыйДокумент = МенеджерЗаписи.ТелоРеестра.Получить();
    
    АдресВременногоХранилища = ПоместитьВоВременноеХранилище(ТекстовыйДокумент);
    
    Возврат АдресВременногоХранилища;
    
КонецФункции

&НаКлиенте
Процедура КомандаПоказатьТекстФайла(Команда)
    
    Если ТекстРеестра.КоличествоСтрок() = 0 Тогда
        
        АВХ = ПолучитьТекстИзДокумента(Объект.Ссылка);
        ТекстРеестра = ПолучитьИзВременногоХранилища(АВХ);

    КонецЕсли;
    
КонецПроцедуры

&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
    
    АдресВременногоХранилищаТекстаРеестра = ПоместитьВоВременноеХранилище(ТекстРеестра,УникальныйИдентификатор);
    
    ТекстРеестра.Очистить();
    
КонецПроцедуры

&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
    
    ПослеЗаписиНаСервере(АдресВременногоХранилищаТекстаРеестра,Объект.Ссылка);
    
    ТекстРеестра = ПолучитьИзВременногоХранилища(АдресВременногоХранилищаТекстаРеестра);
    
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ПослеЗаписиНаСервере(Знач АВХ,Знач ОбъектСсылка)
    
    ТекстовыйДокумент = ПолучитьИзВременногоХранилища(АВХ);
    
    МенеджерЗаписи = РегистрыСведений.МЭК_ФайлыРеестров.СоздатьМенеджерЗаписи();
    МенеджерЗаписи.ДокументРеестра = ОбъектСсылка;
    МенеджерЗаписи.ТелоРеестра = Новый ХранилищеЗначения(ТекстовыйДокумент);
    
    МенеджерЗаписи.Записать();
    
КонецПроцедуры


итого по 7 секунд на чтение и запись
22 Fragster
 
гуру
20.05.15
15:10
> ТекстРеестра.Очистить();

хитрО!
23 RomaH
 
naïve
20.05.15
15:31
(22) а как еще от тяжелого контекста избавиться?
24 RomaH
 
naïve
21.05.15
08:33
странно - (21) работает так же долго на сохранение
а вот через двоичные данные - то быстро


&НаСервереБезКонтекста
Функция ПолучитьТекстИзДокумента(Знач ОбъектСсылка)
    
    МенеджерЗаписи = РегистрыСведений.МЭК_ФайлыРеестров.СоздатьМенеджерЗаписи();
    
    МенеджерЗаписи.ДокументРеестра = ОбъектСсылка;
    
    МенеджерЗаписи.Прочитать();
    
    ТекстовыйДокумент = МенеджерЗаписи.ТелоРеестра.Получить();
    
    АдресВременногоХранилища = ПоместитьВоВременноеХранилище(ТекстовыйДокумент);
    
    Возврат АдресВременногоХранилища;
    
КонецФункции

&НаКлиенте
Процедура КомандаПоказатьТекстФайла(Команда)
    
    Если ТекстРеестра.КоличествоСтрок() = 0 Тогда
        
        АВХ = ПолучитьТекстИзДокумента(Объект.Ссылка);
        ДанныеХранилища = ПолучитьИзВременногоХранилища(АВХ);
        
        Если ТипЗнч(ДанныеХранилища) = Тип("ТекстовыйДокумент") Тогда
            ТекстРеестра = ДанныеХранилища;
        Иначе
            ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xml");
            ДанныеХранилища.Записать(ИмяВременногоФайла);
        
            ТекстРеестра.Прочитать(ИмяВременногоФайла,Неопределено);
        КонецЕсли;

    КонецЕсли;
    
КонецПроцедуры

&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
    
    
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
    ТекстРеестра.Записать(ИмяВременногоФайла);
    
    //АдресВременногоХранилищаТекстаРеестра = ПоместитьВоВременноеХранилище(ТекстРеестра,УникальныйИдентификатор);
        
    ТекстРеестра.Очистить();
    
    ДвоичныеДанные = Новый ДвоичныеДанные(ИмяВременногоФайла);
    
    АдресВременногоХранилищаТекстаРеестра = ПоместитьВоВременноеХранилище(ДвоичныеДанные,УникальныйИдентификатор);
    
КонецПроцедуры

&НаСервере
Процедура ПриЗаписиНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
    
    ПриЗаписиНаСервереБезКонтекста(АдресВременногоХранилищаТекстаРеестра,Объект.Ссылка);
    
КонецПроцедуры

&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
    
    //ТекстРеестра = ПолучитьИзВременногоХранилища(АдресВременногоХранилищаТекстаРеестра);
    
    ДанныеХранилища = ПолучитьИзВременногоХранилища(АдресВременногоХранилищаТекстаРеестра);
    
    Если ТипЗнч(ДанныеХранилища) = Тип("ТекстовыйДокумент") Тогда
        ТекстРеестра = ДанныеХранилища;
    Иначе
        ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xml");
        ДанныеХранилища.Записать(ИмяВременногоФайла);
        
        ТекстРеестра.Прочитать(ИмяВременногоФайла,Неопределено);
    КонецЕсли;
    
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ПриЗаписиНаСервереБезКонтекста(Знач АВХ,Знач ОбъектСсылка)
    
    ТекстовыйДокумент = ПолучитьИзВременногоХранилища(АВХ);
    
    МенеджерЗаписи = РегистрыСведений.МЭК_ФайлыРеестров.СоздатьМенеджерЗаписи();
    МенеджерЗаписи.ДокументРеестра = ОбъектСсылка;
    МенеджерЗаписи.ТелоРеестра = Новый ХранилищеЗначения(ТекстовыйДокумент);
    
    МенеджерЗаписи.Записать();
    
КонецПроцедуры

Компьютеры — это как велосипед. Только для нашего сознания. Стив Джобс