Tengo un procedimiento almacenado que se ejecuta mucho más rápido desde SQL Server Management Studio (2 segundos) que cuando se ejecuta con System.Data.SqlClient.SqlCommand
(el tiempo de espera después de 2 minutos).alguna consulta SQL mucho más lento cuando se utiliza con SqlCommand?
¿Cuál podría ser el motivo de esto?
Detalles: en SQL Server Management Studio esta se ejecuta en 2 segundos (en la base de datos de producción):
EXEC sp_Stat @DepartmentID = NULL
En .NET/C# los siguientes tiempos de espera después de 2 minutos (en la base de datos de producción) :
string selectCommand = @"
EXEC sp_Stat
@DepartmentID = NULL";
string connectionString = "server=***;database=***;user id=***;pwd=***";
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(selectCommand, connection))
{
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
}
}
}
}
también probé con selectCommand = "sp_Stat"
, CommandType = StoredProcedure
, y un SqlParameter
, pero es el mismo resultado.
Y sin EXEC
es el mismo resultado también.
En una base de datos de desarrollo casi vacía de datos, ambos casos finalizan en menos de 1 segundo. Por lo que está relacionado con que hay una gran cantidad de datos en la base de datos, pero parece ocurrir sólo de .NET ...
lo que Marc Gravell escribió sobre diferentes valores SET
hace la diferencia en el caso presentado.
de SQL Server mostró que SQL Server Management Studio ejecuta los siguientes SET
's de que el Proveedor de .NET SQL Data cliente no:
SET ROWCOUNT 0
SET TEXTSIZE 2147483647
SET NOCOUNT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ARITHABORT ON
SET LOCK_TIMEOUT -1
SET QUERY_GOVERNOR_COST_LIMIT 0
SET DEADLOCK_PRIORITY NORMAL
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
SET ANSI_NULLS ON
SET ANSI_NULL_DFLT_ON ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
SET CURSOR_CLOSE_ON_COMMIT OFF
SET IMPLICIT_TRANSACTIONS OFF
SET QUOTED_IDENTIFIER ON
SET NOEXEC, PARSEONLY, FMTONLY OFF
Cuando he incluido estos, la misma consulta tomaron la misma cantidad de tiempo en SSMS y .NET. Y el responsable SET
es ...
SET ARITHABORT ON
¿Qué he aprendido? Tal vez de usar un generador de perfiles en vez de adivinar ...
(La solución en un principio parecía estar relacionado con descubrimiento de parámetros. Pero yo había mezclado algunas cosas ...)
Una cosa más a tener en cuenta: si usted tiene una penalización de rendimiento con 'ARITHABORT OFF' se le puede unir dos tablas mediante una cadena y un campo numérico. En mi caso, la adición de un simple 'ISNUMERIC (string_field) = 1' cheque _antes_ la unión resuelto el problema :) – Loris
Nunca hubiera considerado este - pregunta muy muy útil/respuesta! :) Solo tenemos una consulta SQL sin procesar que se ejecuta a través de Dapper y el mismo SET fue el culpable. Tenga en cuenta – Jedidja
de establecer ARITHABORT ON en la capa de aplicación .. "agregando ARITHABORT SET ON para su procedimiento no es una solución. Parecerá a trabajar cuando lo pruebas. Pero eso es sólo porque a crear el procedimiento que obligó a una nueva compilación" Artículo completo aquí: http://www.sommarskog.se/query-plan-mysteries.html –