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