visual studio resultados generador ejecutar desde consultas consulta conectar con como comando asignar c# .net sql-server performance sqlconnection

c# - studio - ejecutar comando sql en visual basic



¿Es mejor ejecutar muchos comandos sql con una conexión, o reconectarse cada vez? (5)

Aquí está mi código de prueba, que parece sugerir que es mejor conectarse varias veces en lugar de solo una vez.

¿Estoy haciendo algo mal?

int numIts = 100; Stopwatch sw = new Stopwatch(); sw.Start(); using (SqlConnection connection = new SqlConnection(connectionParameters)) { connection.Open(); for(int i = 0; i < numIts; i++) { SqlCommand command = new SqlCommand(sqlCommandName, connection); command.CommandType = CommandType.StoredProcedure; command.Parameters.AddWithValue(par1Name, par1Val); command.Parameters.AddWithValue(par2Name, par2Val); using(SqlDataReader reader = command.ExecuteReader()) { } } } sw.Stop(); TimeSpan durationOfOneConnectionManyCommands = sw.Elapsed; Console.WriteLine(durationOfOneConnectionManyCommands); sw.Reset(); sw.Start(); for(int i = 0; i < numIts; i++) { using (SqlConnection connection = new SqlConnection(connectionParameters)) { connection.Open(); SqlCommand command = new SqlCommand(sqlCommandName, connection); command.CommandType = CommandType.StoredProcedure; command.Parameters.AddWithValue(par1Name, par1Val); command.Parameters.AddWithValue(par2Name, par2Val); using(SqlDataReader reader = command.ExecuteReader()) { } } } sw.Stop(); TimeSpan durationOfManyConnections = sw.Elapsed; Console.WriteLine(durationOfManyConnections);

Salida:

//output: //00:00:24.3898218 // only one connection established //00:00:23.4585797 // many connections established. // //output after varying parameters (expected much shorter): //00:00:03.8995448 //00:00:03.4539567

Actualizar:

Bien, entonces aquellos que dijeron que sería más rápido con una conexión lo tienen. (aunque la diferencia es marginal, si la hay). Aquí está el código revisado y el resultado:

public void TimingTest() { numIts = 1000; commandTxt = "select " + colNames + " from " + tableName; OneConnection(); ManyConnections(); OneConnection(); } private void ManyConnections() { Stopwatch sw = new Stopwatch(); sw.Start(); for (int i = 0; i < numIts; i++) { using (SqlConnection connection = new SqlConnection(connectionParameters)) { connection.Open(); using (SqlCommand command = connection.CreateCommand()) { command.CommandText = commandTxt; using (SqlDataReader reader = command.ExecuteReader()) { } } } } sw.Stop(); TimeSpan durationOfManyConnections = sw.Elapsed; Console.WriteLine("many connections: " + durationOfManyConnections); } private void OneConnection() { Stopwatch sw = new Stopwatch(); sw.Start(); using (SqlConnection connection = new SqlConnection(connectionParameters)) { connection.Open(); for (int i = 0; i < numIts; i++) { using (SqlCommand command = connection.CreateCommand()) { command.CommandText = commandTxt; using (SqlDataReader reader = command.ExecuteReader()) { } } } } sw.Stop(); TimeSpan durationOfOneConnectionManyCommands = sw.Elapsed; Console.WriteLine("one connection: " + durationOfOneConnectionManyCommands); }

Salida:

one connection: 00:00:08.0410024 many connections: 00:00:08.7278090 one connection: 00:00:08.6368853 one connection: 00:00:10.7965324 many connections: 00:00:10.8674326 one connection: 00:00:08.6346272

Actualizar:

la diferencia es más notable si uso SQLConnection.ClearAllPools() después de cada función:

Salida:

one connection: 00:00:09.8544728 many connections: 00:00:11.4967753 one connection: 00:00:09.7775865


Dado que .NET reutiliza las conexiones ("agrupación de conexiones"), no hay mucha sobrecarga al crear una nueva instancia de DbConnection varias veces seguidas. ADO.NET solo reutilizará la conexión bajo el capó. Por eso es bueno que deseche el objeto SqlConnection cada vez que le dice a .NET que puede devolverlo al grupo.

Sin embargo, puede aumentar el rendimiento de varias inserciones utilizando el procesamiento por lotes de ADO.NET . En ese caso, puede tener fácilmente varios miles de inserciones por segundo. Si el rendimiento es crítico, incluso puede considerar usar SQLBulkCopy .

Además, su primer par de resultados es bastante extraño: ¿30 s por 100 inserciones?


De forma predeterminada, SqlConnection utilizará la agrupación de conexiones. Por lo tanto, es muy probable que su código no abra muchas conexiones en ambos casos.

Puede controlar si SqlConnection utilizará la agrupación habilitando o deshabilitando la agrupación en la cadena de conexión, dependiendo de la base de datos para la que se encuentre su cadena de conexión, la sintaxis variará.

Consulte here para obtener información si utiliza MSSQLServer. Intente establecer Pooling = false en la cadena de conexión y vea si hace una diferencia.


Definitivamente, es mejor tener una conexión. Tal vez está ejecutando su punto de referencia con una pequeña cantidad de datos. Intenta aumentar el número a 1,000 o 10,000.

Otro punto es que, dependiendo de la configuración de su aplicación, puede pensar que está ejecutando varias conexiones, pero .NET está agrupando las conexiones para usted, por lo que básicamente está ejecutando las mismas conexiones.


En general, la agrupación de conexiones de .NET debería hacer que “no importe”, ya que hace un gran trabajo de reciclaje de conexiones para usted. Pero mi práctica es usar una sola conexión para un montón de transacciones que sé que se llevarán a cabo juntas. Creo que sus tiempos son una indicación de que el grupo de conexiones está haciendo su trabajo y simplemente tiene variaciones en las ejecuciones.


SqlClient reunirá sus conexiones. En su primer caso con uno abierto, hará el trabajo de abrir la conexión. Cada otra ejecución utilizará la conexión agrupada. Si invierte su orden y hace "muchas conexiones" primero, esperaría que viera el resultado opuesto.