8.х Загрузка больших объемов данных

Тема в разделе "Общие вопросы "1С:Предприятие 8"", создана пользователем nbIpKuH_BaH9I, 1 июн 2015.

  1. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    600 тыс. это здорово. Я с таким объемом не сталкивался. Чисто в теории интересно осилит ли 1С. И как долго подбор будет открываться.
  2. TopicStarter Overlay
    nbIpKuH_BaH9I
    Offline

    nbIpKuH_BaH9I Модераторы Команда форума Модератор

    Регистрация:
    16 сен 2009
    Сообщения:
    6.977
    Симпатии:
    397
    Баллы:
    104
    А документ все равно не поддерживает больше 99999 строк :). Ну и да, загибается 1С. 10000 строк уже документ тупит долго при обычном открытии. Я в коде специально прописал, чтобы можно было менять это значение. Ну сами понимаете, я же не могу по 1000 строк сделать 600 документов. :)
  3. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    Что кстати значит "комп осиляет только первые 80 тыс. штук"? А дальше?
  4. TopicStarter Overlay
    nbIpKuH_BaH9I
    Offline

    nbIpKuH_BaH9I Модераторы Команда форума Модератор

    Регистрация:
    16 сен 2009
    Сообщения:
    6.977
    Симпатии:
    397
    Баллы:
    104
    Мой комп вылетает на 80000 :). Сервак пока не рискую брать под это
    --- Объединение сообщений, 1 июн 2015 ---
    Дальше появляется виндовское окошко "Недостаточно памяти"
  5. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    Обработку смотреть значит надо. Вероятно память у тебя течет.
  6. Draco
    Offline

    Draco Модераторы Команда форума Модератор

    Регистрация:
    28 окт 2009
    Сообщения:
    13.628
    Симпатии:
    946
    Баллы:
    204
    В общем все сколняются к тому что я в самом начале написал что раз ф том файле где не можете вести, надо иметь отдельный файл или базу где храниться то что выгружали или нет и что грузить порциями.
    Насчет фаловых групп то актуально для больших баз и если есть много винтов свободных.
    Обычно это либо банки либо билинговые системы. там как есть + так есть и - при такой работе.
    для баз с количеством пользователей до 100-150 не думаю что актуально
  7. TopicStarter Overlay
    nbIpKuH_BaH9I
    Offline

    nbIpKuH_BaH9I Модераторы Команда форума Модератор

    Регистрация:
    16 сен 2009
    Сообщения:
    6.977
    Симпатии:
    397
    Баллы:
    104
    Ну в обработке все просто. Получаю файл из аксеса. Данные храню в таблице значений (естественно занимает память). Потом запросом отбираю нужные позиции для обработки. В цикле выполняю действия с этими позициями. Опять память жрется. Что тут еще можно сделать?
    --- Объединение сообщений, 1 июн 2015 ---
    Пользователи меняют сами значения реквизитов, так что уже состав будет другим. Они могут в течении месяца изменить несколько сотен.
  8. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    Там не все хорошо в обработке.
    То что вижу сразу:
    1) Процедура записи в лог мне не очень нравится. Зачем каждый раз читать файл лога? Я использую такую:
    Код:
    Процедура ЗаписатьИнформациюВЛог(Информация, КаталогСФайламиЛога = "", ИмяФайлаЛога = "errorlog", ДобавлятьДатуКИмениФайла = Истина, ДобавлятьПереносСтрокиПослеОтметкиВремени = Истина) Экспорт
       
        ИмяФайла = "" + ИмяФайлаЛога + ?(ДобавлятьДатуКИмениФайла, "_" + Формат(ТекущаяДата(), "ДФ=yyyy-MM-dd"), "") + ".log";
        Если ПустаяСтрока(КаталогСФайламиЛога) Тогда
            РабочийКаталог = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(глЗначениеПеременной("глТекущийПользователь"), "ОсновнойКаталогФайлов");
    
            // Если рабочий каталог не указан получим каталог временных файлов прогаммы
            Если ПустаяСтрока(РабочийКаталог) Тогда
                РабочийКаталог = КаталогВременныхФайлов();
            КонецЕсли;
        Иначе
            РабочийКаталог = КаталогСФайламиЛога;
        КонецЕсли;
        // Так как при различных указаниях рабочего каталога возможно наличие или отсутствие
        // последнего слеша, приведем строку каталога к унифицированному виду - без слеша на конце.
        Если Прав(РабочийКаталог, 1) = "\" Тогда
            РабочийКаталог = Лев(РабочийКаталог, СтрДлина(РабочийКаталог) - 1);
        КонецЕсли;
       
        ПолноеИмяФайла = РаботаСФайлами.ПолучитьИмяФайла(РабочийКаталог, РаботаСФайлами.УдалитьЗапрещенныеСимволыИмени(ИмяФайла));
       
        Попытка
            ФайлРегистрации = Новый ЗаписьТекста(ПолноеИмяФайла, КодировкаТекста.ANSI, , Истина);
    
            ТекстСообщения = Формат(ТекущаяДата(), "ДФ='dd.MM.yyyy HH:mm:ss'")
                            + ?(ДобавлятьПереносСтрокиПослеОтметкиВремени, Символы.ПС, "   ")
                            + Информация;
            ФайлРегистрации.ЗаписатьСтроку(ТекстСообщения);
            ТекстСообщения = "";
    
            ФайлРегистрации.Закрыть();
           
            ФайлРегистрации = Неопределено;
        Исключение
            ЗаписьЖурналаРегистрации("ОшибкаЗаписьИнформацииВЛог", УровеньЖурналаРегистрации.Ошибка, , , "Не удалось сделать запись в лог об ошибках. Текст сообщения был:" + ТекстСообщения);
        КонецПопытки;
       
        //Чистим за собой
        ПолноеИмяФайла = "";
        РабочийКаталог = "";
        ИмяФайла = "";
       
    КонецПроцедуры
    

    2) ПолучитьТаблицуИзAccess()
    Все подобные строки убрать:
    Код:
                
                    TNR_Артикул             = СокрЛП(Recordset.Fields(i).Value);
                    НоваяСтрока.TNR_Артикул = TNR_Артикул;
    
                    BENEN_НемецкоеНаименование             = СокрЛП(Recordset.Fields(i).Value);
                   НоваяСтрока.BENEN_НемецкоеНаименование = BENEN_НемецкоеНаименование;
    
    и т.д.
    Сразу одной строкой делать, без промежуточных переменных.

    3) ПолучитьТаблицуИзAccess()
    КОМ объекты = Неопределено, после того как они не нужны.


    4) ЗаполнитьМенеджерВременныхТаблиц().
    Строка:
    Код:
    ТаблицаСДаннымиИзФайла = Неопределено; // очищаем память
    
    Очищать надо, я за. Но из этой процедуры строку убрать. ТаблицаСДаннымиИзФайла заполнялась не здесь, значит не здесь ее и отчищать. Отчищать в процедуре ЗагрузкаИзAccess(). (и да, не тестировал насколько критично, но я перед обнулением переменной с ТЗ, еще предварительно строки в ней отчищаю).

    5) Важно: ИзменитьДанныеНоменклатуры()
    Там есть строка:
    Код:
    НоваяСтрока.ЕдиницаИзмерения  = ВыборкаРезультатаЗапроса.Ссылка.ОсновнаяЕдиницаИзмерения;
    
    ОсновнаяЕдиницаИзмерения - ОБЯЗАТЕЛЬНО получить в запросе, не тащить ее через ссылку. В данном случае я думаю это даст видимое ускорение.

    6) СоздатьДанныеНоменклатуры()
    Строка:
    Код:
    НовыйЭлемент.Родитель  = Справочники.Номенклатура.НайтиПоНаименованию("Прайс-лист от импортера"); // Прайс-лист от импортера
    
    Родитель = константа. => получение родителя вынести из цикла.

    7) СоздатьДанныеНоменклатуры()
    Не вникал до конца в логику - там не совсем понятное мне вложение блоков Попытка-Исключение. А что будет если единицу измерения записать не удастся?
  9. TopicStarter Overlay
    nbIpKuH_BaH9I
    Offline

    nbIpKuH_BaH9I Модераторы Команда форума Модератор

    Регистрация:
    16 сен 2009
    Сообщения:
    6.977
    Симпатии:
    397
    Баллы:
    104
    1) Согласен. Не углядел. Старую свою процедуру взял из шаблона.
    2) Здесь не понял. По индексу предлагаешь обращаться?
    3) Да, забыл очистить.
    4) Не углядел.
    5) Исправлю, но до этого даже и не доходит :D. Обрубается еще на создании новых.
    6) Исправлю.
    7) Единицу измерения можно записать только после того как ссылка на номенклатуру будет, а т.к. она новая, то и ссылки еще нет. Поэтмоу приходит сначала записать номенклатуру, дабы получить ссылку и уже потом создать единицу измерения, проставить ее в номенклатуре, а потом вновь перезаписать номенклатуру. Здесь большой косяк.
    --- Объединение сообщений, 1 июн 2015 ---
    shurikvz, Можно я буду называть тебя "Зоркий глаз" или "Всевидящее око" :D. Ты всегда в моем быдло-коде косяки находишь.
  10. XXL
    Offline

    XXL Опытный в 1С Команда форума

    Регистрация:
    22 янв 2007
    Сообщения:
    1.159
    Симпатии:
    19
    Баллы:
    29
    У меня аналогичная задача с теми же исходными данными.
    Грузим в три этапа:
    1. проверяем номенклатуру - если новая, записываем.
    2. грузим аналоги, если есть.
    3. создаём документы установки цен (по три документа на закупочную, нормативную и розничную цену). Ограничение на документ 10 000 строк.

    Данные считываются напрямую из Аксесс, без временных таблиц. Не вылетает.

    Делается два-три дня, оставляем на ночь и забиваем (может можно и быстрее, но изначально делала не я и переделывать нет времени).
  11. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    Код:
    НоваяСтрока.TNR_Артикул = СокрЛП(Recordset.Fields(i).Value);
    
    --- Объединение сообщений, 1 июн 2015 ---
    7) Там две попытки одна в другую вложенных. Смысл в двух штуках? Если единицу измерения записать не удастся номенклатура все равно не запишется.
  12. TopicStarter Overlay
    nbIpKuH_BaH9I
    Offline

    nbIpKuH_BaH9I Модераторы Команда форума Модератор

    Регистрация:
    16 сен 2009
    Сообщения:
    6.977
    Симпатии:
    397
    Баллы:
    104
    А, то что сначала переменную создаю?! Это лично для меня более наглядно. На производительность это вообще не влияет.

    Ну здесь по сути тоже на трудоемкость попытка не влияет. Ну можно ее убрать. Это не никак не отразится. Факт остается фактом. Что приходится по несколько раз перезаписывать данные. И, похоже, с этим никак не справиться. :(

    В моем случае временные таблицы нужны для более быстрого отбора. И тебе советую также сделать, будет быстрее работать :)
  13. XXL
    Offline

    XXL Опытный в 1С Команда форума

    Регистрация:
    22 янв 2007
    Сообщения:
    1.159
    Симпатии:
    19
    Баллы:
    29
    В задачах стоит оптимизировать, но пока есть более важные дела. Как руки доберутся, будешь мне помогать:)

    Запчасти VAG грузишь?
  14. TopicStarter Overlay
    nbIpKuH_BaH9I
    Offline

    nbIpKuH_BaH9I Модераторы Команда форума Модератор

    Регистрация:
    16 сен 2009
    Сообщения:
    6.977
    Симпатии:
    397
    Баллы:
    104
    Андрей, вариант с еще одной базой мне не совсем понятен. Можешь еще раз рассказать?
    --- Объединение сообщений, 1 июн 2015 ---
    Нет, Мерседес от импортера :)
    Да не вопрос. Я только за...
  15. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    1) Это было не из-за производительности. Я не уверен в 1С, а точнее в том, насколько хорошо (быстро) 1С отчищает память под неиспользуемые локальные переменные. Наглядность в данном случае можно выразить комментарием.

    2) И да, ты не поверишь, но:
    Код:
    НоваяСтрока.TNR_Артикул = СокрЛП(Recordset.Fields(i).Value);
    
    работает быстрее чем:
    Код:
    TNR_Артикул = СокрЛП(Recordset.Fields(i).Value);
    НоваяСтрока.TNR_Артикул = TNR_Артикул;
    
  16. XXL
    Offline

    XXL Опытный в 1С Команда форума

    Регистрация:
    22 янв 2007
    Сообщения:
    1.159
    Симпатии:
    19
    Баллы:
    29
    Почти угадала:)
  17. TopicStarter Overlay
    nbIpKuH_BaH9I
    Offline

    nbIpKuH_BaH9I Модераторы Команда форума Модератор

    Регистрация:
    16 сен 2009
    Сообщения:
    6.977
    Симпатии:
    397
    Баллы:
    104
    Что-то я дико сомневаюсь, что это "быстрее" будет хоть как то заметно. По логике я понимаю, что 1 строка кода обработается быстрее чем 2.
  18. Draco
    Offline

    Draco Модераторы Команда форума Модератор

    Регистрация:
    28 окт 2009
    Сообщения:
    13.628
    Симпатии:
    946
    Баллы:
    204
    Вариант еще с одной базой следующий
    Я бы все делал а Аксесе, там дело плевое есть БД которую тебе присылают, я не знаю база это или таблицабудем исходить что таблица. в аксесе делаешь 2 точно таких же таблицы
    Итого у тебя 3 одинаковых таблицы только в свою одну добавляешь реквизит Выгружался
    Так вот из таблицы поставщика выборкой запросом получаешь данные которых у тебя нет в твоей таблице с признаком загружали инсертиком быстро добавляешь .ти данные в две таблицы в одной из них устанавливая признак выгружался
    Затем когда надо делать выгрузку в 1С берешь третью таблицу оттуда все данные и выгружаешь ее, а затем чистишь таблицу
    Итого у тебя получается
    1 таблица поставщика
    2 твоя таблица со всей номенклатурой что приходила и признаком что бы знать что брать,а что нет из файла,
    3 таблица для выгружки, очищаемае - выгрузили очистили, что бы не лезть во вторую таблицуи не перебирать повтороно что выгруждла а что нет из 600 тыс записей

    Ну аналогичную байду можно и через буферную базу 1С сделать. Просто на аксесе проше и быстрее бутет.


    Либо рассматривай варианты выгрузки в xml файлы и их загрузки, а не через com. так быстрее будет
  19. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    Существенно не будет.
    Но как я написал - эти изменения не из-за быстродействия.
  20. TopicStarter Overlay
    nbIpKuH_BaH9I
    Offline

    nbIpKuH_BaH9I Модераторы Команда форума Модератор

    Регистрация:
    16 сен 2009
    Сообщения:
    6.977
    Симпатии:
    397
    Баллы:
    104
    Убей меня. Опять не понимаю. Зачем плодить так много таблиц, когда я в 1С это все делаю. Хоть что ты сделай, все равно нужно будет проверять базу 1С с файлом, который поставщик присылает. Тогда смысл с других таблицах?! Я не уловил опять.
    --- Объединение сообщений, 1 июн 2015 ---
    Понял. Спасибо. Учту.

Поделиться этой страницей