txt registro programacion modificar leer lectura guardar escritura dev datos crear como buscar ats archivos archivo c# ms-access oledb

programacion - ¿Cuál es la forma más rápida de insertar 100 000 registros en un archivo MDB en C#



lectura y escritura de archivos en c++ (3)

Sé que esta pregunta es bastante general, pero he buscado todo el día y no he podido encontrar la forma adecuada de hacerlo.

Aquí está mi código para insertar unos 100 000 registros ficticios en un archivo MDB utilizando C #.

OleDbConnection con = new OleDbConnection(); string dbProvider = "PROVIDER=Microsoft.Jet.OLEDB.4.0;"; string dbSource = "Data Source = D:/programming/sample.mdb"; con.ConnectionString = dbProvider + dbSource; OleDbCommand cmd = new OleDbCommand(); cmd.Connection = con; cmd.CommandText = "INSERT INTO tblBooks (Title, Price, Tag, Author) VALUES (@title, @price, @tag, @author)"; cmd.Parameters.AddWithValue("@title", "Dummy Text 1"); cmd.Parameters.AddWithValue("@price", 10); cmd.Parameters.AddWithValue("@tag", "Dummy Text 2"); cmd.Parameters.AddWithValue("@author", "Dummy Text 3"); con.Open(); for (int i = 0; i < 100000; i++) { cmd.ExecuteNonQuery(); } con.Close();

Este código tarda alrededor de un minuto en ejecutarse. ¿Esto es normal? ¿Cuál es la forma correcta de hacerlo más rápido?


Puede usar una tabla de números para agregar varias filas idénticas, por ejemplo:

INSERT INTO aTable ( aText, aNumber ) SELECT @param1 , @param2 FROM Numbers WHERE Numbers.Number<1000

La tabla de Números es:

Number 0 1 2 <...>


Si ya tiene una "tabla de números" disponible (con al menos 100.000 filas), la respuesta de Remou casi con certeza hará el trabajo más rápido. Probé una prueba rápida en VBA y la consulta

Dim t0 As Single t0 = Timer CurrentDb.Execute _ "INSERT INTO tblBooks (Title, Price, Tag, Author) " & _ "SELECT ''Dummy Text 1'', 10, ''Dummy Text 2'', ''Dummy Text 3'' FROM Numbers", _ dbFailOnError Debug.Print Format(Timer - t0, "0.0") & " seconds"

creó las 100.000 filas en menos de 2 segundos.

Sin embargo, si todavía no tiene una tabla de números, primero deberá crear esa tabla, de modo que si se trata de un requisito de una sola vez, es mejor que optimice su código.

El código tal como se publicó en su pregunta tomó 45 segundos en mi máquina. Dos mejoras que redujeron significativamente el tiempo de ejecución fueron:

  1. Use .Prepare() : eso solo redujo el tiempo transcurrido a 16 segundos

  2. Utilice una OleDbTransaction : Envolver los insertos en una transacción (además de usar .Prepare() ) redujo aún más el tiempo transcurrido a 10 segundos.

El código modificado se ve así:

var sw = new System.Diagnostics.Stopwatch(); sw.Start(); OleDbConnection con = new OleDbConnection(); string dbProvider = "PROVIDER=Microsoft.Jet.OLEDB.4.0;"; string dbSource = "Data Source = C:/Users/Gord/Desktop/speed.mdb"; con.ConnectionString = dbProvider + dbSource; con.Open(); OleDbCommand cmd = new OleDbCommand(); cmd.Connection = con; cmd.CommandText = "INSERT INTO tblBooks (Title, Price, Tag, Author) VALUES (?,?,?,?)"; cmd.Parameters.Add("?", OleDbType.VarWChar, 255); cmd.Parameters.Add("?", OleDbType.Currency); cmd.Parameters.Add("?", OleDbType.VarWChar, 255); cmd.Parameters.Add("?", OleDbType.VarWChar, 255); cmd.Prepare(); cmd.Parameters[0].Value = "Dummy Text 1"; cmd.Parameters[1].Value = 10; cmd.Parameters[2].Value = "Dummy Text 2"; cmd.Parameters[3].Value = "Dummy Text 3"; OleDbTransaction trn = con.BeginTransaction(); cmd.Transaction = trn; for (int i = 0; i < 100000; i++) { cmd.ExecuteNonQuery(); } trn.Commit(); con.Close(); sw.Stop(); Console.WriteLine(String.Format("{0:0.0} seconds", sw.ElapsedMilliseconds / 1000.0));


(Respuesta de bonificación :)

En caso de que alguien se pregunte si OleDbDataAdapter puede insertar las filas más rápido, parece que no. El siguiente código crea los 100.000 registros ...

var da = new OleDbDataAdapter("SELECT [ID], [Title], [Price], [Tag], [Author] FROM [tblBooks] WHERE False", con); var cb = new OleDbCommandBuilder(da); cb.QuotePrefix = "["; cb.QuoteSuffix = "]"; var dt = new System.Data.DataTable(); da.Fill(dt); for (int i = 0; i < 100000; i++) { System.Data.DataRow dr = dt.NewRow(); dr["Title"] = "Dummy Text 1"; dr["Price"] = 10; dr["Tag"] = "Dummy Text 2"; dr["Author"] = "Dummy Text 3"; dt.Rows.Add(dr); } da.Update(dt);

... pero tarda aproximadamente un 30% más en ejecutarse que el código original en la pregunta.