Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Abfrage extrem langsam im Code, aber schnell in SSMS

Ihr Code in SSMS ist nicht derselbe Code, den Sie in Ihrer Anwendung ausführen. Diese Zeile in Ihrer Anwendung fügt einen NVARCHAR-Parameter hinzu:

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

während Sie es im SSMS-Skript als VARCHAR:

deklarieren
declare @clientID varchar(200)

Aufgrund der Regeln der Data Type Precedence ist Where client_id = @clientID Ausdruck in Ihrer Abfrage ist nicht SARG-fähig, wobei @clientID ist vom Typ NVARCHAR (ich mache einen Vertrauensvorschuss und gehe davon aus, dass client_id Spalte ist vom Typ VARCHAR). Die Anwendung erzwingt somit einen Tabellenscan, bei dem die SSMS-Abfrage eine schnelle Schlüsselsuche durchführen kann. Dies ist ein bekanntes und verstandenes Problem bei der Verwendung von Parameters.AddWithValue und wurde bereits in vielen Artikeln diskutiert, z. siehe Auswirkungen von Datenzugriffscode auf die Datenbankleistung. Sobald das Problem verstanden ist, sind die Lösungen trivial:

  • Parameter mit dem Konstruktor hinzufügen, der einen Typ akzeptiert:Parameters.Add("@clientID", SqlDbType.Varchar, 200) (und tun Übergeben Sie die explizite Länge, um Cache-Verschmutzung zu vermeiden, siehe Abfrageleistung und planen Sie Cache-Probleme, wenn die Parameterlänge nicht korrekt angegeben ist

  • oder Setzen Sie den Parameter in den SQL-Text um:where client_id = cast(@clientID as varchar(200)) .

Die erste Lösung ist überlegen, da sie zusätzlich zum SARG-Fähigkeitsproblem das Cache-Verschmutzungsproblem löst.

Ich würde Ihnen auch empfehlen, Slow in the Application, Fast in SSMS? Leistungsgeheimnisse verstehen