Как улучшить производительность MS Access INSERT - PullRequest
2 голосов
/ 22 декабря 2011

У меня есть программа на C ++, которая вставляет около миллиона записей в БД MS Access, используя OLEDBConnection.Для этого я выполнил запрос INSERT INTO миллионы раз, чтобы вставить вставленные записи, которые занимают довольно много времени.

Данные генерируются в программе в виде массива, будет ли это любоеДругой способ, которым я могу загрузить данные в базу данных за один шаг для повышения производительности?

Спасибо!

Цикл, который я использую для вставки записей в настоящее время

for (int i = 0; i < populationSize; i++){
    insertSQL = "INSERT INTO [" + pTableName + "] (" + columnsName + ") VALUES (" + columnsValue[i] + ");";`
    outputDBConn->runSQLEdit(insertSQL);
}

Метод запуска SQL-запроса

void DBConnector::runSQLEdit(String^ query){
    SQLCMD = gcnew OleDbCommand( query, dbConnection );
    SQLCMD->CommandTimeout = 30;
    dbConnection->Open();
    SQLCMD->ExecuteNonQuery();
    dbConnection->Close();
    }

Ответы [ 2 ]

3 голосов
/ 22 декабря 2011

Кажется очень неэффективным , чтобы открыть / закрыть соединение для каждого оператора вставки.

Стандартный подход выглядит примерно так:

  1. Открыть соединение.
  2. Начать транзакцию, если поддерживается.(Это часто очень важно для баз данных с транзакциями.)
  3. Вставка. Повторите этот шаг при необходимости.
  4. Подтвердите транзакцию, если поддерживается.
  5. Закройте соединение.

Обновление: Следующее не относится к MS Access.Access не поддерживает вставку нескольких строк из литерала .Он поддерживает только вставку нескольких строк из существующего источника данных.(Хотя здесь может работать «workabout» . В любом случае, наиболее важным является ограничение количества транзакций.)

Еще одна вещь, которую можно сделать, этосоздайте команду single insert, которая добавляет несколько записей одновременно.Это можно сделать с помощью нескольких операторов или вставки из нескольких записей (если поддерживается).Это может быть или не быть значительно быстрее, чем просто выше (зависит от других факторов, таких как задержка сети и ядро ​​базы данных) и, вероятно, потребуется адаптировать, чтобы соответствовать ограничениям базы данных (например, может быть тольковыполнимо для нескольких сотен записей одновременно).Это должно только после правильного использования соединения / транзакции, как описано выше.

Я не удивлюсь, если мы уже сделали библиотеки / модули "массовой вставки", плавающие вокруг ..и я не использую MS Access, поэтому я могу только надеяться, что приведенные выше предложения были полезны: -)

Удачное кодирование.

1 голос
/ 22 декабря 2011

Не делайте ОДНУ вставку на команду.Измените свой код на что-то вроде этого:

string strSQLCommand;
for (int i = 0; i < populationSize; i++){
strSQLCommand += "INSERT INTO [" + pTableName + "] (" + columnsName + ") VALUES (" + columnsValue[i] + ");";`
}
outputDBConn->runSQLEdit(strSQLCommand );

Я не уверен, каков максимальный размер буфера команды, поэтому сделайте несколько проверок, а затем получите лучшее значение, чтобы сделать несколько "разрывов" на каждомX вставки.

...