Здравствуйте Ростислав Глухов, вы писали:
РГ>Наверное, из-за неправильного использования ADO... РГ>Типы курсоров, например, РГ>или CacheSize у RecordSet'a не установил...
Огромное спасибо за ответ, но пока все равно не очень получается. Типы курсоров пробовал разные и с кэшем игрался, но улучшений не получил. Был ли у вас опыт такого перехода и если да, то отразилось ли это на скорости работы с базой ?
Re[3]: Заменил ODBC API на ADO - все замедлилось в 10 раз
Здравствуйте sergey, вы писали:
S>Огромное спасибо за ответ, но пока все равно не очень получается. Типы курсоров пробовал разные и с кэшем игрался, но улучшений не получил. Был ли у вас опыт такого перехода и если да, то отразилось ли это на скорости работы с базой ?
Опыта _перехода_ с ODBC на АДО нет
Есть опыт использования АДО отдельно
Странно, что улучшений нет, я когда оптимизировал CacheSize, получал улучшения в скорости в разы (не помню точно, что -то около 5 крат)
Для разных операций следует использовать разные параметры, напр для Грида CacheSize>10
как-то будет неочень при прогрутке туда-сюда
А для начальной загрузки справочника типа (ID,Name) CacheSize надо поболе
про влияния раздичнах параметров типа типаКурсора, adComText/adCmdTable и пр.
стОит посмотреть mdacsdk, там есть пример с замером скорости. Правда, на ВБ, но показательно...
- А Вы что курите?
— Минздрав предупреждает
Re: Заменил ODBC API на ADO - все замедлилось в 10 раз
Здравствуйте VladD2, вы писали:
VD>Здравствуйте sergey, вы писали:
S>>Заменил ODBC API на ADO — работа с базой сильно замедлилась. Кто подскажет, почему ?
VD>А что за задачи то?
Есть довольно большая (по кол-ву таблиц) база. Раньше для ODBC API были написаны парочка функций для удобного вытаскивания содержимого таблиц в си-шные структурки. Т.е. по структуре базы генерились си-шные файлы с объявлением структур, соответствующих таблицам базы. Потом при запросе (простом) по таблице поля этих структур биндились к запросу и все было хорошо. При переходе на ADO я хотел сохранить эту схему, только ходьбу к базе заменить на ADO-шную. Текст на ODBC API рисовать не буду — больно здоровый, а ADO-шный текст смотрите в нижних сообщениях...
Большое спасибо за участие !
Re[2]: Заменил ODBC API на ADO - все замедлилось в 10 раз
Здравствуйте WindJammer, вы писали:
WJ>Здравствуйте sergey, вы писали:
S>>Заменил ODBC API на ADO — работа с базой сильно замедлилась. Кто подскажет, почему ?
WJ>А вы фрагменты кода (того и другого) покажите, может и найдется человек, который скажет, где собака порылась.
Вот фрагметец ADO-шной реализации класса, который раньше был на ODBC API. Старый печатать не буду — он довольно большой да и вряд ли чем поможет...
Спасибо большое и Вам за то что не прошли мимо !
Statement::Statement()
{
m_pConn = 0;
}
Statement::~Statement()
{
}
void Statement::Connect()
{
if (m_pConn)
return;
m_conn.CreateInstance("ADODB.Connection");
// ................................................................
strcpy (Buf, "");
GetPrivateProfileString("Data source", "DataSourceName", "", Buf, sizeof(Buf), "actmed.ini");
if (!strlen(Buf))
{
::MessageBox (NULL, "ActionMed not properly installed on this computer", "Message", MB_OK);
return;
}
CString conn_str;
conn_str.Format("DSN=%s", Buf);
m_conn->Open(_bstr_t(conn_str), "SQLDBA", "ACTMED", 0);
// ................................................................
m_rs .CreateInstance("ADODB.Recordset");
if (g_ActmedConn.IsConnected())
m_pConn = &g_ActmedConn;
m_FirstRecord = TRUE;
m_Opened = FALSE;
}
RETCODE Statement::ExecDirect(const char * sql_cmd)
{
if (!m_pConn) return SQL_ERROR;
if (m_rs->EndOfFile == VARIANT_TRUE)
return SQL_ERROR;
return SQL_SUCCESS;
}
RETCODE Statement::Bind (unsigned short n, char * buf, int len)
{
m_BindColumn.Add(n);
m_BindPtr .Add(buf);
m_BindLen .Add(len);
m_BindType .Add(SQL_C_DEFAULT);
return SQL_SUCCESS;
}
RETCODE Statement::cBind(unsigned short n, char * buf, int len)
{
m_BindColumn.Add(n);
m_BindPtr .Add(buf);
m_BindLen .Add(len);
m_BindType .Add(SQL_C_CHAR);
return SQL_SUCCESS;
}
RETCODE Statement::lBind(unsigned short n, long * buf, int len)
{
m_BindColumn.Add(n);
m_BindPtr .Add((char *)buf);
m_BindLen .Add(len);
m_BindType .Add(SQL_C_LONG);
return SQL_SUCCESS;
}
RETCODE GetNext(Statement & hs, int type, char * struct_ptr)
{
RETCODE retcode = AdjustRC(hs.Fetch());
if (retcode != SQL_SUCCESS)
return retcode;
CString str;
COleVariant val;
char * p = struct_ptr;
for (int col = 0; col < TF[type].FCount; col ++)
{
val = hs.m_flds->Item[COleVariant((long)col)]->Value;
str = val.bstrVal;
str.TrimRight();
strcpy(p, str);
p += TF[type].Fields[col].FLength;
}
return retcode;
}
Re[3]: Заменил ODBC API на ADO - все замедлилось в 10 раз
Здравствуйте WindJammer, вы писали:
WJ>Здравствуйте sergey, вы писали:
S>>Вот фрагметец ADO-шной реализации класса, который раньше был на ODBC API. Старый печатать не буду — он довольно большой да и вряд ли чем поможет...
WJ>Возможно, есть проблемы в том, как вы получаете данные (метод Fetch()). WJ>Почему бы не попробовать ADOBinding для получения данных от рекордсета?
WJ>А что у вас за источник данных, в смысле какая БД? WJ>Строка Connection как выглядит?
Это, наверное, правильно про ADOBinding. Спасибо, обязательно попробую. Кстати, если есть кусочек текста, проясняющий работу с этим чудом — пришлите, буду очень признателен.
А БД у меня — SQL Server. Подключался и через ODBC DSN и напрямую — большой разницы в скорости не заметил (на глаз не видно).
Re[5]: Заменил ODBC API на ADO - все замедлилось в 10 раз
Здравствуйте sergey, вы писали:
S>Это, наверное, правильно про ADOBinding. Спасибо, обязательно попробую. Кстати, если есть кусочек текста, проясняющий работу с этим чудом — пришлите, буду очень признателен. S>А БД у меня — SQL Server. Подключался и через ODBC DSN и напрямую — большой разницы в скорости не заметил (на глаз не видно).
Соединение через OLEDBSQL должно быть быстрее ODBC (на глаз получается процентов 20-30)
ADOBinding:
Определить класс рекордсета, типа:
// ODRecordset.h: interface for the CODRecordset class.
//
//////////////////////////////////////////////////////////////////////
if (FAILED(m_rs->Open(sql_cmd, m_conn.GetInterfacePtr(),
adOpenDynamic,
adLockOptimistic,
adCmdUnknown)))
return SQL_ERROR;
m_rs->CacheSize = 10; // сейчас в кэше только одна запись, 10 будет после movenext
если только для заполнения структур, то наверное, лучше так
m_rs->CacheSize = 10;
if (FAILED(m_rs->Open(sql_cmd, m_conn.GetInterfacePtr(),
adOpenForwardonly, // этот курсор полегче
adLockOptimistic,
adCmdText))) // или adCmdTable
return SQL_ERROR;
- А Вы что курите?
— Минздрав предупреждает
Re[6]: Заменил ODBC API на ADO - все замедлилось в 10 раз
Огромное спасибо за просвещение (всем кто отвечал) !
Думаю, что теперь почти все ясно.
Я провел замеры скорости на едином примере для:
— ODBC API
— ADO через ODBC
— ADO через SQLOLEDB provider
Получил следующее распределение мест:
1. ADO через SQLOLEDB provider ( 85%)
2. ODBC API ( 90%)
3. ADO через ODBC (100%)
SQLOLEDB без ADO не пробовал — не разобрался еще.
Еще раз спасибо !
Успехов !
P.S.
Все ли хорошо у Вас с работой ?
Re[7]: Заменил ODBC API на ADO - все замедлилось в 10 раз