Rendimiento de proveedores de acceso – Parte 1 .NET

En ocasiones nos podemos preguntar que proveedor usar al desarrollar nuestra capa de acceso a datos, usamos OLEDB, ODBC o SQLClient. que ventajas tienen unos, cuales otros… En estos post intentaré ver la diferencia de rendimiento entre los diferentes proveedores y que ventajas podemos tener si usamos unos u otros.

Para esta prueba vamos a utilizar una tabla de una sola columna (nvarchar(max) y varios millones de columnas. La query que vamos a ejecutar es la siguiente:

SELECT TOP 5000000 * FROM HashTable

En este primer articulo vamos a centrarnos en código manejado y las diferencias de rendimiento entre usar SQLClient, Odbc, Oledb. Todas las pruebas se realizan en local y conectando con TCP.

SQLClient

Para empezar veremos la que probablemente sea forma más común de acceder a SQL Server desde .NET, SQLClient. El código que vamos a ejecutar es el siguiente:

for (int j = 0; j < 10; j++)
{
SqlConnection conn = new SqlConnection("Data Source=PGAVELA-02\\KAWORU;Initial Catalog=PerfTest;Integrated Security=SSPI");
SqlCommand cmd = new SqlCommand("SELECT TOP 5000000 * FROM HashTable");
cmd.Connection = conn;
cmd.CommandTimeout = 0;
conn.Open();
startTick = Environment.TickCount;
cmd.Prepare();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
reader.GetString(0);
}
endTick = Environment.TickCount;
Console.WriteLine(String.Format("Round {0} Time: {1} ms", j, endTick - startTick));
SQLClient += (endTick - startTick);
conn.Close();
}

Console.WriteLine(String.Format("Avg Time: {0} ms", SQLClient / 10.0));

Como podemos ver ejecutamos 10 veces la query y al final obtenemos el tiempo medio.

Managed Code And SQLClient
Round 0 Time: 15803 ms
Round 1 Time: 15709 ms
Round 2 Time: 15694 ms
Round 3 Time: 15802 ms
Round 4 Time: 15757 ms
Round 5 Time: 15818 ms
Round 6 Time: 15585 ms
Round 7 Time: 15568 ms
Round 8 Time: 15601 ms
Round 9 Time: 15678 ms
Avg Time: 15701,5 ms

Como podemos ver el el tiempo medio es de 15.7 segundos.

OleDB

La segunda prueba la vamos a realizar con OleDB, el código que vamos a ejecutar es practicamente el mismo que con SQLClient, pero cambiando a las clases apropiadas de OleDB.

Console.WriteLine("Managed Code And OLEDB");
for (int j = 0; j < 10; j++)
{
OleDbConnection OleDbConn = new OleDbConnection("Provider=SQLNCLI10.1;Integrated Security=SSPI;Initial Catalog=PerfTest;Data Source=PGAVELA-02\\KAWORU");
OleDbCommand OleDbCmd = new OleDbCommand("SELECT TOP 5000000 * FROM HashTable");
OleDbCmd.Connection = OleDbConn;
OleDbCmd.CommandTimeout = 0;
OleDbConn.Open();
startTick = Environment.TickCount;
OleDbCmd.Prepare();
OleDbDataReader OleDbReader = OleDbCmd.ExecuteReader();
while (OleDbReader.Read())
{
OleDbReader.GetString(0);
}
endTick = Environment.TickCount;
Console.WriteLine(String.Format("Round {0} Time: {1} ms", j, endTick - startTick));
OleDb += (endTick - startTick);
OleDbConn.Close();
}
Console.WriteLine(String.Format("Avg Time: {0} ms", OleDb / 10.0));

Los tiempos para OleDB son los siguientes:

Managed Code And OLEDB
Round 0 Time: 35334 ms
Round 1 Time: 34492 ms
Round 2 Time: 34913 ms
Round 3 Time: 33961 ms
Round 4 Time: 33618 ms
Round 5 Time: 33634 ms
Round 6 Time: 34242 ms
Round 7 Time: 34024 ms
Round 8 Time: 33962 ms
Round 9 Time: 34040 ms
Avg Time: 34222 ms

El tiempo medio es de 34.2 segundos, mucho más alto que el SQLClient.

ODBC

Como en las otras pruebas usaremos el mismo código cambiando solo las clases relativas al proveedor, el código usado es:

Console.WriteLine("Managed Code and ODBC");

            for (int j = 0; j < 10; j++)
{
OdbcConnection OdbcConn = new OdbcConnection("Driver={SQL Server Native Client 10.0};Server=PGAVELA-02\\KAWORU;Database=PerfTest;Trusted_Connection=yes");
OdbcCommand OdbcCmd = new OdbcCommand("SELECT TOP 5000000 * FROM HashTable");
OdbcCmd.CommandTimeout = 0;
OdbcCmd.Connection = OdbcConn;
OdbcConn.Open();
startTick = Environment.TickCount;
OdbcCmd.Prepare();
OdbcDataReader OdbcReader = OdbcCmd.ExecuteReader();

while (OdbcReader.Read())
{
OdbcReader.GetString(0);
}
endTick = Environment.TickCount;
Console.WriteLine(String.Format("Round {0} Time: {1} ms", j, endTick - startTick));
Odbc += (endTick - startTick);
OdbcConn.Close();
}
Console.WriteLine(String.Format("Avg Time: {0} ms", Odbc / 10.0));

Los tiempos para este proveedor son los siguientes:

Managed Code and ODBC
Round 0 Time: 23603 ms
Round 1 Time: 23572 ms
Round 2 Time: 23697 ms
Round 3 Time: 23603 ms
Round 4 Time: 23821 ms
Round 5 Time: 23634 ms
Round 6 Time: 23587 ms
Round 7 Time: 23619 ms
Round 8 Time: 23728 ms
Round 9 Time: 23462 ms
Avg Time: 23632,6 ms

Como podemos ver el tiempo medio es de 23.6 segundos.

 

Conclusiones

Como podemos ver el método que más rendimiento ofrece SQLClient sin ninguna duda, seguido de ODBC. OLEDB se queda con mucho retraso en último lugar. Además el proveedor OLEDB para SQL Server se considera deprecado (https://blogs.msdn.com/b/sqlnativeclient/archive/2011/08/29/microsoft-is-aligning-with-odbc-for-native-relational-data-access.aspx) por tanto no recomendamos utilizar OLEDB para nuevos desarrollos.

Ahora entre SQLClient o ODBC con cual nos quedamos. Si necesitamos rendimiento sin ninguna duda optaremos por SQLClient.

Pablo Gavela López – Microsoft Customer Support Services