Пакетное обновление MS Access через ADO.Net и COM-совместимость

Это своего рода продолжениеэта тема, Это все с.Net 2.0; по крайней мере для меня.

По сути, Марк (OP сверху) попробовал несколько различных подходов для обновления таблицы MS Access с 100 000 записей и обнаружил, что использование соединения DAO было примерноВ 10-30 раз быстрее чем с помощью ADO.Net. Я пошел практически по тому же пути (примеры ниже) и пришел к тому же выводу.

Я просто пытаюсь понятьПочему OleDB и ODBC намного медленнее, и я хотел бы услышать, нашел ли кто-нибудь лучший ответ, чем DAO, после этой публикации в 2011 году. Я действительно предпочел бы избегать DAO и / или Automation, так как они собираются требовать клиента на машине либо Access, либо ядро базы данных, которое можно распространять (или я застрял с DAO 3.6, которая не поддерживает .ACCDB).

Оригинальная попытка; ~ 100 секунд для 100 000 записей / 10 столбцов:

Dim accessDB As New OleDb.OleDbConnection( _ 
                      "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & _
                                accessPath & ";Persist Security Info=True;")
accessDB.Open()

Dim accessCommand As OleDb.OleDbCommand = accessDB.CreateCommand
Dim accessDataAdapter As New OleDb.OleDbDataAdapter( _
                                   "SELECT * FROM " & tableName, accessDB)
Dim accessCommandBuilder As New OleDb.OleDbCommandBuilder(accessDataAdapter)

Dim accessDataTable As New DataTable
accessDataTable.Load(_Reader, System.Data.LoadOption.Upsert)

//This command is what takes 99% of the runtime; loops through each row and runs 
//the update command that is built by the command builder. The problem seems to 
//be that you can't change the UpdateBatchSize property with MS Access
accessDataAdapter.Update(accessDataTable)

Во всяком случае, я подумал, что это действительно странно, поэтому я попробовал несколько вариантов одного и того же:

Выключение OleDB для ODBCЦикл по таблице данных и запуск инструкции INSERT для каждой строкиЭто то, что .Update делает в любом случаеИспользование поставщика ACE вместо Jet (ODBC и OleDB)Запуск обновления адаптера данных из цикла DataReader.ReadИз разочарования; это было весело.

Наконец, я попытался использовать DAO. Код должен в основном делать то же самое; за исключением того, что это явно не так, потому что это работает за ~ 10 секунд.

 Dim dbEngine As New DAO.DBEngine
 Dim accessDB As DAO.Database = dbEngine.OpenDatabase(accessPath)
 Dim accessTable As DAO.Recordset = accessDB.OpenRecordset(tableName)

While _Reader.Read
    accessTable.AddNew()
      For i = 0 To _Reader.FieldCount - 1
        accessTable.Fields(i).Value = _Reader.Item(i).ToString
      Next
    accessTable.Update()
End While

Несколько других заметок:

Во всех примерах все преобразуется в строки, чтобы все было максимально просто и согласованно.Исключение: в моем первом примере, используя функцию Table.Load, я этого не делаю, потому что ... ну, я действительно не могу, но я сделал в основном то же самое, когда перебрал ридер и построил команды вставки (что во всяком случае, что он делает). Это не помогло.Для каждого поля ... Следующее против Поля (i) против Поля (имени) не имеет значения для меняКаждый запущенный мной тест начинался с пустой предварительно созданной таблицы данных в только что сжатой базе данных AccessЗагрузка считывателя данных в таблицу данных в памяти занимает ~ 3 секундыЯ не думаю, что это проблема с маршалингом данных, потому что в посте Марка указывалось, что загрузка текстового файла с помощью автоматизации происходит так же быстро, как DAO - во всяком случае, он не должен маршалировать данные при использовании ODBC / OleDB, но этодолжен при использовании автоматизацииВсе это беспокоит меня гораздо больше, чем следовало, потому что это не имеет смысла

Надеюсь, кто-нибудь сможет пролить свет на это ... это просто странно. Заранее спасибо!

Ответы на вопрос(2)

Ваш ответ на вопрос