Показать сообщение отдельно
Старый 16.02.2017, 13:06   #9  
online
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,052 / 1779 (66) ++++++++
Регистрация: 12.10.2004
А на что у вас тратится время при синхронизации ?
Можно выделить несколько причин замедления :
1. Медленное обращение к метаданным SQL сервера - когда долго идет сканирование каие таблички
есть в наличии и.т.п.
2. Долгое создание индексов
3. Долгое создание полей.
4. Долгое пересоздание табличек при изменении длины строковых полей.

Предлагаю рассмотреть каждый фактор и дальше уже решать что делать.
По п.1 - можно пошаманить с SQL - как ускорить процесс. Например, на форуме была тема где это обсуждалось применительно к ораклу - там шаманили с материализованными вьюхами и.т.п.
Долгая синхронизация
Возможно для SQL тоже можно что-то такое применить. Или иной способ. Мне тоже не нравится как долго он делает сканирование - сравниваю скорость синхронизации на 2009-й под Ораклом и на 2012 R3 под SQL - намного дольше начитывает данные о табличках. Т.е. явно подтормаживает обращение в системным вьюхам содержащим инфу а табличках, их полях и индексах. Наверняка этот процесс можно ускорить - надо покопать соответствующие ресурсы по SQL серверу.

По п.2 можно индексы отдельно создавать - онлайн. Если база большая то БД скорее всего в Enterprise версии, так что позволит это сделать.

По п.3 надо смотреть - не готов что-то советовать.

По п.4 Тоже решаемо. Описывал способ решения тут:
Длина номера фактуры, накладной больше 20 символов.
делается несложно.
Джоб для правки SQLDictionary :
X++:
static void SQLDictionaryFix(Args _args)
{
    int                         strSize = 20; //pkoz 28.10.2013
    AsciiIo                     Source;
    dialog                      dialog = new dialog("");
    dialogfield                 fileName;
    filenameopen                _fileName;
    container                   OneRec;
    InvoiceId                   invoiceID;
    container                   con;
  // pkoz 15.06.2006 -->
    custTable                   custTable;
    custSettlement              _custSettlement;
  // pkoz 15.06.2006 <--

    identifiername              tableName;
    identifiername              fieldName;

    TableId                     TableId;
    FieldId                     FieldId;

    SQLDictionary               SQLDictionary;
    SQLDictionary               SQLDictionary2;
    ;
//    appl.setDefaultCompany("904");
//    appl.setDefaultCompany("905");
    fileName            = dialog.addFieldValue(typeId(filenameopen),_filename,"Файл с данными");
//    fileName.value(@"c:\_\Estate.csv");
//    fileName.value(@"c:\_\SQLDictionaryFix.csv"); //pkoz 28.10.2013
//    fileName.value(@"c:\_\FK2.csv"); //pkoz 28.10.2013
    fileName.value(@"c:\_\FK_126468_myach.csv"); //pkoz 21.09.2015
    dialog.run();
    if ( dialog.closedOk())
    {
        _filename = filename.value();

        // pkoz, 11.04.2014 -->
        if ( Box::yesNo_Net(strFMT("Длина %1 ?", strSize), DialogButton::No) != DialogButton::Yes)
        {
            return;
        }
        // pkoz, 11.04.2014 <--

        Source = SysDataIntegration::openFile(_filename,"R",";");
        if ( source)
        {
            ttsBegin;
            while(source.status() == IO_status::Ok)
            {
                // [invoiceID] = source.read();
                con = source.read();
                if (con)
                {
                    tableName = GRD_ConPeekStr( con, 1);
                    fieldName = GRD_ConPeekStr( con, 2);
                    TableId = tablename2Id( tableName );
                    if ( !TableId )
                    {
                        warning(strFMT("Не определили TableId по %1 и %2", tableName, fieldName ));
                        continue;
                    }

                    fieldId = fieldName2id( TableId, fieldName );
                    if ( !fieldId )
                    {
                        warning(strFMT("Не определили fieldId по %1 и %2", tableName, fieldName ));
                        continue;
                    }


                    SQLDictionary = null;
                    select forUpdate SQLDictionary
                    where
                        SQLDictionary.name    == fieldName &&
                        SQLDictionary.tabId   == TableId &&
                        SQLDictionary.fieldId == fieldId
                    ;
                    if ( !SQLDictionary )
                    {
                        warning(strFMT("Не определили SQLDictionary по %1 и %2", tableName, fieldName ));
                        continue;
                    }

                    if ( SQLDictionary.fieldType != Types::RString &&
                         SQLDictionary.fieldType != Types::String &&
                         SQLDictionary.fieldType != Types::VarString
                       )
                    {
                        warning(strFMT("Поле в SQLDictionary не строковое по %1 и %2", tableName, fieldName ));
                        continue;
                    }

                    if ( SQLDictionary.strSize > strSize )
                    {
                        warning(strFMT("Поле в SQLDictionary уже длиннее по %1 и %2", tableName, fieldName ));
                        continue;
                    }

                    SQLDictionary.strSize = strSize;
                    SQLDictionary.update();
                    info(strFMT("Обновили по %1 и %2", tableName, fieldName ));

                }
            }
            ttsCommit;
        }
    }

    info( "ок" );

}
Скрипты для SQL тоже легко генерятся если удалось составить перечень табличек и полей.

Еще как вариант, если много модификаций переносится, то может имеет смысл не скопом все накатывать а разбить процесс на несколько обновлений - чтобы каждый раз небольшие изменения в БД вносились. Можно ведь сперва БД изменять пошагово, а потом уже накатить/включить бизнеслогику.

Последний раз редактировалось Logger; 16.02.2017 в 13:50.
За это сообщение автора поблагодарили: mazzy (2), macklakov (5), trud (1), Ace of Database (3), Ivanhoe (5), Товарищ ♂uatr (1).