Что-то я засомневался и решил тоже провести тестирование. Подключения в режиме доверительного соединения (Windows-аутентификация). Результаты такие
ODBC (Connection) = около 20 минут - если запуск в 3-х уровневой конфигурации на стороне клиента
ODBC (Connection) = около 5 минут - если запуск в 2-х уровневой конфигурации или в 3-х уровневой конфигурации на стороне сервера
ODBC (DRIVER=SQL Server) = около 5 минут
ADO (Provider=SQLNCLI) = около 13 минут - это Native 2005
ADO (Provider=sqloledb) = около 16 минут
Другими словами, результат вполне ожидаемый. ODBC работает быстрее, чем ADO. Однако при использовании объекта Connection в случае работы в 3-х уровневой конфигурации следует обратить внимание на то, на какой стороне выполняется код. На стороне клиента или на стороне сервера.
Я тестировал на таблице InventTable. У нас в ней около 50 тысяч записей и эта таблица виртуализирована, поэтому нет фильтра по DataAreaId. Всего в таблице более 150 полей, но я считывал только первые 81 поле, а в примере, приведенном ниже отобразил только первые 22
X++:
// Сравнение скорости работы ODBC по сравнению с ADO
static void JOB_ODBC_vs_ADO(Args _args)
{
int timeNowBegin;
Connection connection;
OdbcConnection connectBase;
LoginProperty lp;
str strConnectionString;
Statement statement;
ResultSet resultSet;
CCADOConnection adoConnection;
CCADOCommand adoCommand;
CCADORecordSet adoRecordSet;
CCADOFields fields;
CCADOField field;
InventTable inventTableTmp,
inventTableTmpADO;
int totalI,
nextI;
SysOperationProgress sysOperaionProgress;
;
// Количество для индикатора прогресса
totalI = (select count(RecId) from inventTable).RecId;
sysOperaionProgress = new SysOperationProgress(2);
#aviFiles
sysOperaionProgress.setAnimation(#aviTransfer);
sysOperaionProgress.setCaption("Сравнение ODBC и ADO");
sysOperaionProgress.setTotal(totalI, 1);
sysOperaionProgress.setText("ODBC",1);
sysOperaionProgress.setTotal(totalI, 2);
sysOperaionProgress.setText("ADO",2);
timeNowBegin = timeNow();
strConnectionString = strFmt("DRIVER=SQL Server;SERVER=%1;DataBase=%2;Trusted_Connection=Yes","MyServerName","MyBaseName");
lp = new LoginProperty();
lp.setOther(strConnectionString);
connectBase = new OdbcConnection(LP);
statement = connectBase.createStatement();
/*
// Это для тестирования прмого подключения
connection = new Connection();
statement = connection.createStatement();
*/
resultSet = statement.executeQuery("SELECT * FROM inventTable with (nolock)");
nextI = 0;
inventTableTmp.setTmp();
while (resultSet.next())
{
sysOperaionProgress.setText(strFmt("ODBC всего %1 осталось %2",totalI,totalI-nextI),1);
sysOperaionProgress.incCount(1,1);
nextI++;
inventTableTmp.clear();
InventTableTmp.ItemGroupId = resultSet.getString(1);
InventTableTmp.ItemId = resultSet.getString(2);
InventTableTmp.ItemName = resultSet.getString(3);
InventTableTmp.ItemType = resultSet.getInt(4);
InventTableTmp.PurchModel = resultSet.getInt(5);
InventTableTmp.Height = resultSet.getReal(6);
InventTableTmp.Width = resultSet.getReal(7);
InventTableTmp.SalesModel = resultSet.getInt(8);
InventTableTmp.CostGroupId = resultSet.getString(9);
InventTableTmp.ReqGroupId = resultSet.getString(10);
InventTableTmp.PrimaryVendorId = resultSet.getString(11);
InventTableTmp.NetWeight = resultSet.getReal(12);
InventTableTmp.Depth = resultSet.getReal(13);
InventTableTmp.UnitVolume = resultSet.getReal(14);
InventTableTmp.BOMUnitId = resultSet.getString(15);
InventTableTmp.Density = resultSet.getReal(16);
InventTableTmp.ScrapTypeId = resultSet.getString(17);
InventTableTmp.Dimension[1] = resultSet.getString(18);
InventTableTmp.Dimension[2] = resultSet.getString(19);
InventTableTmp.Dimension[3] = resultSet.getString(20);
InventTableTmp.Dimension[4] = resultSet.getString(21);
InventTableTmp.Dimension[5] = resultSet.getString(22);
// Все поля перечислять не буду
inventTableTmp.insert();
} // while (resultSet.next())
info("ODBC="+time2str(timeNow()-timeNowBegin,1,1));
timeNowBegin = timeNow();
adoConnection = new CCADOConnection();
// Это драйвер NATIVE 2005
// adoConnection.open("Provider=SQLNCLI;Server=MySereverName;Database=MyBaseName;Trusted_Connection=yes;");
adoConnection.open("Provider=sqloledb;Data Source=MyServerName;Initial Catalog=MyBaseName;Integrated Security=SSPI;");
adoCommand = new CCADOCommand();
adoCommand.activeConnection(adoConnection);
adoCommand.commandType(1);
adoCommand.commandText("SELECT * FROM inventTable with (nolock)");
adoRecordSet = adoCommand.execute();
fields = adoRecordSet.fields();
nextI = 0;
inventTableTmpADO.setTmp();
while (! adoRecordSet.EOF())
{
sysOperaionProgress.setText(strFmt("ADO всего %1 осталось %2",totalI,totalI-nextI),2);
sysOperaionProgress.incCount(1,2);
nextI++;
inventTableTmpADO.clear();
inventTableTmpADO.ItemGroupId = fields.itemIdx(0).value();
inventTableTmpADO.ItemId = fields.itemIdx(1).value();
inventTableTmpADO.ItemName = fields.itemIdx(2).value();
inventTableTmpADO.ItemType = fields.itemIdx(3).value();
inventTableTmpADO.PurchModel = fields.itemIdx(4).value();
inventTableTmpADO.Height = fields.itemIdx(5).value();
inventTableTmpADO.Width = fields.itemIdx(6).value();
inventTableTmpADO.SalesModel = fields.itemIdx(7).value();
inventTableTmpADO.CostGroupId = fields.itemIdx(8).value();
inventTableTmpADO.ReqGroupId = fields.itemIdx(9).value();
inventTableTmpADO.PrimaryVendorId = fields.itemIdx(10).value();
inventTableTmpADO.NetWeight = fields.itemIdx(11).value();
inventTableTmpADO.Depth = fields.itemIdx(12).value();
inventTableTmpADO.UnitVolume = fields.itemIdx(13).value();
inventTableTmpADO.BOMUnitId = fields.itemIdx(14).value();
inventTableTmpADO.Density = fields.itemIdx(15).value();
inventTableTmpADO.ScrapTypeId = fields.itemIdx(16).value();
inventTableTmpADO.Dimension[1] = fields.itemIdx(17).value();
inventTableTmpADO.Dimension[2] = fields.itemIdx(18).value();
inventTableTmpADO.Dimension[3] = fields.itemIdx(19).value();
inventTableTmpADO.Dimension[4] = fields.itemIdx(20).value();
inventTableTmpADO.Dimension[5] = fields.itemIdx(21).value();
// Все поля перечислять не буду
inventTableTmpADO.insert();
adoRecordSet.moveNext();
}
info("ADO="+time2str(timeNow()-timeNowBegin,1,1));
sysOperaionProgress.kill();
}