Скорость ADO при работе с Oracle
От: Аноним  
Дата: 02.06.02 10:21
Оценка:
Доброе время суток!
Я занимаюсь перекачкой данных из XML в Oracle, и с самого начала встала проблема тормознутости работы моей программы. Программа делает тривиальную вещь: строит запрос (параметризованный) на INSERT, потом в цикле задает значения параметров и выполняет запрос. Проблема заключается в том, что скорость выполнения INSERTа — 1000 записей за 20 секунд, что исключительно медленно. В результате долгих исследований, оказалось, что запрос выполняется тормознуто только в первый раз. Если запустить приложение во второй раз, скорость работы возрастает примерно втрое, что уже неплохо. Я подозреваю, что Oracle запрос кэширует (м это подтверждается моими экспериментами). И вот встает вопрос, как сделать, чтобы запрос выполнялся быстрее сразу после первого INSERTа, а не после завершения приложения?
Или я что-то не так понимаю?
Re: Скорость ADO при работе с Oracle
От: Slayer Россия  
Дата: 03.06.02 02:51
Оценка:
Здравствуйте Аноним, Вы писали:

А>Доброе время суток!

А>Я занимаюсь перекачкой данных из XML в Oracle, и с самого начала встала проблема тормознутости работы моей программы. Программа делает тривиальную вещь: строит запрос (параметризованный) на INSERT, потом в цикле задает значения параметров и выполняет запрос. Проблема заключается в том, что скорость выполнения INSERTа — 1000 записей за 20 секунд, что исключительно медленно. В результате долгих исследований, оказалось, что запрос выполняется тормознуто только в первый раз. Если запустить приложение во второй раз, скорость работы возрастает примерно втрое, что уже неплохо. Я подозреваю, что Oracle запрос кэширует (м это подтверждается моими экспериментами). И вот встает вопрос, как сделать, чтобы запрос выполнялся быстрее сразу после первого INSERTа, а не после завершения приложения?
А>Или я что-то не так понимаю?


Тут может быть мн-во причин. Без кода что-нить конкретное сказать сложно. Вопросы следующие: Сессии ты каждый раз создаешь или у тебя одна на все запросы? Инсерты по очереди делаешь или одной транзакцией ? и т.п.
Re: Скорость ADO при работе с Oracle
От: Alexey Menkov  
Дата: 04.06.02 03:59
Оценка:
Здравствуйте Аноним, Вы писали:

А>Доброе время суток!

А>Я занимаюсь перекачкой данных из XML в Oracle, и с самого начала встала проблема тормознутости работы моей программы. Программа делает тривиальную вещь: строит запрос (параметризованный) на INSERT, потом в цикле задает значения параметров и выполняет запрос. Проблема заключается в том, что скорость выполнения INSERTа — 1000 записей за 20 секунд, что исключительно медленно. В результате долгих исследований, оказалось, что запрос выполняется тормознуто только в первый раз. Если запустить приложение во второй раз, скорость работы возрастает примерно втрое, что уже неплохо. Я подозреваю, что Oracle запрос кэширует (м это подтверждается моими экспериментами). И вот встает вопрос, как сделать, чтобы запрос выполнялся быстрее сразу после первого INSERTа, а не после завершения приложения?
А>Или я что-то не так понимаю?
Re[2]: Скорость ADO при работе с Oracle
От: Alexey Menkov  
Дата: 04.06.02 04:09
Оценка:
Сделай хранимую процедуру в Oracle и передавай ей параметры.
Re[3]: Скорость ADO при работе с Oracle
От: Аноним  
Дата: 04.06.02 04:30
Оценка:
Здравствуйте Alexey Menkov, Вы писали:


AM>Сделай хранимую процедуру в Oracle и передавай ей параметры.


В том то все и заключается, что все равно что делать — либо делать INSERT, либо делать процедуру. Конечно, разница по скорости есть, но она все равно далека от идеальной. Я все делаю в одной транзакции. Вот кусок кода (заранее прошу прощения за кривой код — все-таки он тестовый):

char buf[1000];
    ora_cnn->Open("Provider=MSDAORA.1;Data Source=myDB;User ID=user1;Password=pwd1;","","",-1);
    ora_rs->Open ( "SELECT * FROM TEST_TAB", 
        _variant_t((IDispatch *)ora_cnn,true), 
        ADODB::adOpenStatic, 
        ADODB::adLockBatchOptimistic, 
        ADODB::adCmdText );
    ora_cmd->ActiveConnection = ora_cnn;
    ora_cmd->CommandType = ADODB::adCmdText;
    const n = 49;
    for ( int i = 0; i < n; i++ ){
        pars[i].CreateInstance ( __uuidof(ADODB::Parameter) );
        pars[i]->Type = ora_rs->Fields->GetItem((long) i)->Type;
        pars[i]->Size = ora_rs->Fields->GetItem((long) i)->DefinedSize;
        pars[i]->Direction = ADODB::adParamInput;
        ora_cmd->Parameters->Append ( pars[i] );
    }
    ora_cnn->BeginTrans ( );

    _bstr_t query = "BEGIN INSERT INTO test_tab1( ";
    for ( i = 0; i < n; i++ ){
        query += ora_rs->Fields->GetItem((long)i)->Name;
        if ( i < n - 1 )
            query += ",";
    }
    query += ") VALUES (";
    for ( i = 0; i < n; i++ ){
        query += _bstr_t("?"); 
        if ( i < n - 1 )
            query += ",";
    }
    query += "); END; ";
    ora_cmd->CommandText = query;
    ora_cmd->PutPrepared ( true );
    
    if ( 1 ){
        for ( int i = 0; i < 500; i++ ){
            try{
                for ( int kk = 0; kk < n; kk++ )
                     pars[kk]->Value = ora_rs->Fields->GetItem((long)kk)->Value;
                ora_cmd->Execute ( 0, 0, ADODB::adExecuteNoRecords );
                ora_rs->MoveNext ();
            } catch(_com_error &a){
                cout << a.Description ();
                return 0;
            }
        }
    }
    ora_cnn->CommitTrans ( );

P.S. Сразу хочу сказать, что на клиенте не тормозит — загрузка процессора на клиенте около 30%, почти все время тратится на Execute. В данном примере данные из таблицы test_tab качаются в test_tab1, у которой идентичная структура. Если убрать PutPrepared, то скорость почти не меняется.
Re: Скорость ADO при работе с Oracle
От: Аноним  
Дата: 11.06.02 06:05
Оценка:
Здравствуйте Аноним, Вы писали:

А>Доброе время суток!

А>Я занимаюсь перекачкой данных из XML в Oracle, и с самого начала встала проблема тормознутости работы моей программы. Программа делает тривиальную вещь: строит запрос (параметризованный) на INSERT, потом в цикле задает значения параметров и выполняет запрос. Проблема заключается в том, что скорость выполнения INSERTа — 1000 записей за 20 секунд, что исключительно медленно. В результате долгих исследований, оказалось, что запрос выполняется тормознуто только в первый раз. Если запустить приложение во второй раз, скорость работы возрастает примерно втрое, что уже неплохо. Я подозреваю, что Oracle запрос кэширует (м это подтверждается моими экспериментами). И вот встает вопрос, как сделать, чтобы запрос выполнялся быстрее сразу после первого INSERTа, а не после завершения приложения?
А>Или я что-то не так понимаю?
Оформить хранимую процедуру в виде пакета и этот пакет загрузить предварительно в разделяемую память
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.