Jest to swego rodzaju kontynuacja do this thread. Wszystko to z . Net 2.0; przynajmniej dla mnie.Aktualizacja danych wsadowych MS Access za pomocą funkcji ADO.Net i COM Interoperability
Zasadniczo Marc (OP z góry) Próbowałem kilka różnych podejść do zaktualizowania tabeli MS Access z 100,000 rekordy i stwierdził, że przy użyciu połączenia DAO była grubsza 10 - 30x szybciej niż przy użyciu ADO.NET. Zszedłem praktycznie tą samą ścieżką (przykłady poniżej) i doszedłem do tego samego wniosku.
Chyba jestem po prostu staramy się zrozumieć dlaczego OleDB i ODBC są o wiele wolniej i chciałabym usłyszeć, jeśli ktoś znalazł lepszą odpowiedź niż DAO od tego stanowiska w 2011 roku będę naprawdę wolą unikać DAO i/lub automatyzacji, ponieważ będą wymagać, aby komputer klienta miał dostęp do redystrybucji lub silnika bazy danych (lub utknąłem z DAO 3.6, który nie obsługuje .ACCDB).
Oryginalna próba; ~ 100 sekund dla 100,000 pozycji/10 kolumn:
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)
Zresztą myślałem, że to było naprawdę dziwne więc próbowałem kilka odmian tej samej rzeczy:
- Przełączanie się OleDB ODBC
- Looping poprzez tabeli danych i prowadzenie INSERT dla każdego wiersza
- to jest to, co robi i tak .Update
- Korzystanie dostawcy ACE zamiast Jet (ODBC i OLEDB)
- Running aktualizację danych z adaptera w pętli DataReader.Read
- z frustracji; to było zabawne.
Wreszcie, próbowałem używać DAO. Kod powinien zasadniczo robić to samo; z wyjątkiem tego, że wyraźnie nie jest, ponieważ działa to w ~ 10 sekund.
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
Kilka innych uwagi:
- Wszystko jest przekształcane na łańcuchy we wszystkich przykładach, aby utrzymać rzeczy tak proste i jak najbardziej spójną
- Wyjątek: W pierwszym przykładzie, stosując funkcji Table.Load, nie robię tego, ponieważ ... cóż, naprawdę nie mogę, ale w zasadzie to samo zrobiłem, kiedy przełączyłem się przez czytnik i zbudowałem polecenia wstawiania (i tak to się dzieje). To nie pomogło.
- Dla każdego pola ... Dalej kontra Pole (i) vs.Pole (nazwa) nie miało znaczenia dla mnie
- Każda próba Pobiegłem rozpoczął z pustego, gotowych tabeli danych w świeżo ubitego bazy danych Access
- załadowaniu Reader danych do tabeli danych w pamięci trwa ~ 3 sekundy
- Nie sądzę, że to problem z gromadzeniem danych, ponieważ post Marca wskazywał, że ładowanie pliku tekstowego za pośrednictwem Automatyzacji jest tak szybkie jak DAO - jeśli w ogóle, to nie powinno marnować danych podczas korzystania z ODBC/OleDB, ale to powinno być przy użyciu Automatyzacji
- Wszystko to przeszkadza mi o wiele bardziej niż powinno, ponieważ nie ma sensu
Mam nadzieję, że ktoś będzie mógł rzucić trochę światła na to ... to po prostu dziwne. Z góry dziękuję!
Dzięki za wyjaśnienie! Wiem, że DAO siedzi prosto na silniku DB, po prostu nigdy nie widziałem * tego * drastycznego uderzenia wydajności po prostu przy użyciu jednej dodatkowej warstwy oprogramowania pośredniego. Czy w takim przypadku główne działanie programu Access jest inne w porównaniu z innymi systemami DBMS, że aktualizacja zwykle uruchamia aktualizację w partiach, zamiast przechodzić przez ODBC dla każdego rekordu? – Karter
Hitem jest ** SO BAD **, ponieważ jest to Access. Nie będzie aż tak źle (tutaj przynęta z płomieniem) a real_ RDBMS, także dla SQL Server (i SQL Server express), możesz użyć klasy 'SqlBulkCopy', która wstawia wiersze z szybkością topienia bliską twarzy. Jeśli możesz, szczerze polecam porzucić MS Access i uruchomić z SQL Express. Używałem programu Access w znacznym stopniu w ciągu dnia i nigdy go nie lubiłem. _ "Ojej, cieszę się, że skorzystałem z dostępu do tego projektu", nie powiedziałam nigdy. –
Nie zgadzam się; ale wiesz, ** dziedzictwo wspiera wszystkie rzeczy ** – Karter