tools studio management code all c# sql sql-server .net-4.0 sql-server-2000

c# - studio - Consulta extremadamente lenta en código pero rápida en SSMS



sql ssms tools (4)

Capture el plan de ejecución desde ambos SSMS cuando ejecute manualmente su consulta y luego desde Profiler cuando esté ejecutando su aplicación. Comparar y contrastar.

Tengo una consulta bastante simple en la que sigo obteniendo tiempos de espera (tarda más de tres minutos en completarse, la detuve antes para poder publicar esta pregunta) sobre cuándo se ejecuta en el código, sin embargo, cuando ejecuto la misma consulta desde la misma computadora en Sql Server Management Studio, la consulta solo tomará 2532 ms la primera consulta cuando los datos no se almacenan en caché en el servidor y 524 ms para consultas repetidas.

Aquí está mi código c #

using (var conn = new SqlConnection("Data Source=backend.example.com;Connect Timeout=5;Initial Catalog=Logs;Persist Security Info=True;User ID=backendAPI;Password=Redacted")) using (var ada = new SqlDataAdapter(String.Format(@" SELECT [PK_JOB],[CLIENT_ID],[STATUS],[LOG_NAME],dt FROM [ES_HISTORY] inner join [es_history_dt] on [PK_JOB] = [es_historyid] Where client_id = @clientID and dt > @dt and (job_type > 4 {0}) {1} Order by dt desc" , where.ToString(), (cbShowOnlyFailed.Checked ? "and Status = 1" : "")), conn)) { ada.SelectCommand.Parameters.AddWithValue("@clientID", ClientID); ada.SelectCommand.Parameters.AddWithValue("@dt", dtpFilter.Value); //ada.SelectCommand.CommandTimeout = 60; conn.Open(); Logs.Clear(); ada.Fill(Logs); //Time out exception for 30 sec limit. }

Aquí está mi código que estoy ejecutando en SSMS, lo saqué directamente de ada.SelectCommand.CommandText

declare @clientID varchar(200) set @clientID = ''138'' declare @dt datetime set @dt = ''9/19/2011 12:00:00 AM'' SELECT [PK_JOB],[CLIENT_ID],[STATUS],[LOG_NAME],dt FROM [ES_HISTORY] inner join [es_history_dt] on [PK_JOB] = [es_historyid] Where client_id = @clientID and dt > @dt and (job_type > 4 or job_type = 0 or job_type = 1 or job_type = 4 ) Order by dt desc

¿Qué está causando la mayor discrepancia por la diferencia en el tiempo?

Para mantener la sección de comentarios limpia, responderé algunas preguntas frecuentes aquí.

La misma computadora y el inicio de sesión se utilizan tanto para la aplicación como para ssms.

Solo se devuelven 15 filas en mi consulta de ejemplo. Sin embargo, es_history contiene 11351699 rows y es_history_dt contiene 8588493 rows . Ambas tablas están bien indexadas y el plan de ejecución en SSMS dice que están utilizando búsquedas de índice para las búsquedas, por lo que son búsquedas rápidas. El programa se está comportando como si no estuviera utilizando los índices para la versión C # de la consulta.


Ejecute DBCC FREEPROCCACHE , como se sugiere here , solo para asegurarse de que el problema no se deba a un plan de ejecución de consultas obsoletas.


Ejecute el generador de perfiles en su conexión c #: puede haber otra actividad en marcha de la que no tenga conocimiento.


Su código en SSMS no es el mismo código que ejecuta en su aplicación. Esta línea en su aplicación agrega un parámetro NVARCHAR:

ada.SelectCommand.Parameters.AddWithValue("@clientID", ClientID);

mientras que en el script SSMS lo declara como VARCHAR:

declare @clientID varchar(200)

Debido a las reglas de precedencia del tipo de datos, la expresión Where client_id = @clientID en su consulta no es compatible con SARG, donde @clientID es de tipo NVARCHAR (estoy haciendo un acto de fe y asumo que la columna client_id es de tipo VARCHAR). Por lo tanto, la aplicación fuerza un escaneo de la tabla donde la consulta SSMS puede hacer una búsqueda rápida de clave. Este es un problema bien conocido y comprendido con el uso de Parámetros.AddWithValue y se ha discutido en muchos artículos antes, por ejemplo. vea Cómo el código de acceso a datos afecta el rendimiento de la base de datos . Una vez que se entiende el problema, las soluciones son triviales:

La primera solución es superior porque resuelve el problema de contaminación de caché además del problema de capacidad SARG.

También te recomendaría leer Lenta en la aplicación, ¿Rápido en SSMS? Entendiendo los misterios del rendimiento