ADO.NET/OleDb経由でJet(Access)データベースに多数のレコードを挿入しようとしています。それはゆっくりと痛みを伴う。遅さは、主にDbDataAdapter.Update
メソッドによるものです。 Microsoftの言葉では、ADO.NET/OleDbを使用してJetデータベースに非常に遅いレコードが挿入される
...これらのステートメントはバッチ処理として実行されません。各行は個別に更新されます。
私のデータベースアプリケーションが古いADOやDAO(AddNew
/Update
ループ付きレコード)を使用してVB6での同等のコードよりも約30倍遅くパフォーマンスを提供しますので、これは本当のWTFです。
SqlClientプロバイダーには、SqlBulkCopy
クラスがあります。 OleDbに相当するものはありますか?
書き込みキャッシングの動作を変更することもできます。 (つまり、各行が挿入された後でキャッシュをフラッシュしないでください)
私はできることは何ですか、またはADO.NETはJetのために壊れていますか?
* 編集済み:ここでは、カットダウンテストデータベースを使用して、私のコードをカットダウンしたバージョンです。
まず、VBA/ADOのバージョン(アクセス2003):
Dim con As ADODB.Connection
Set con = CurrentProject.Connection
con.Execute "DELETE * FROM tblTest", , adCmdText Or adExecuteNoRecords
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
rs.Open "tblTest", con, , adLockPessimistic
Dim i&, t!
t = Timer
For i = 1 To 10000
rs.AddNew
rs!mainKey = i
rs!testColumn = Rnd * 100
rs.Update
Next
rs.Close
Debug.Print "time to add 10000 (by ADO) " & Timer - t
出力:time to add 10000 (by ADO) 0.296875
今ADO.NETのバージョン(2010 VB.NET):
Dim sProvider As String = "PROVIDER = Microsoft.Jet.OLEDB.4.0;"
Dim sDataSource As String = "Data Source = 'C:\test.mdb'"
Dim connection As New OleDbConnection(sProvider & sDataSource)
connection.Open()
Dim q As New OleDbCommand("DELETE * FROM tblTest", connection)
q.ExecuteNonQuery()
Dim ds As New DataSet
Dim selectCmd As OleDbCommand = connection.CreateCommand()
selectCmd.CommandText = "SELECT * FROM tblTest"
Dim da As New OleDbDataAdapter(selectCmd)
da.Fill(ds, "tblTest")
Dim theTable As DataTable = ds.Tables("tblTest")
For i As Integer = 1 To 10000
Dim row = theTable.NewRow()
row.Item("mainKey") = i
row.Item("testColumn") = Rnd() * 100
theTable.Rows.Add(row)
Next i
Dim t! : t = Microsoft.VisualBasic.Timer
Dim cb As New OleDbCommandBuilder(da)
da.Update(ds, "tblTest")
Debug.Print("time to add 10000 (by ADO.NET): " & Microsoft.VisualBasic.Timer - t)
connection.Close()
出力:time to add 10000 (by ADO.NET): 5.859375
あなたがカットダウンコードを投稿することをお勧めします。 –
@Mitch Wheat:OK質問に追加しました。 –
トランザクションを使用しようとしましたか? – FrinkTheBrave