Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Requête extrêmement lente dans le code mais rapide dans SSMS

Votre code dans SSMS n'est pas le même code que vous exécutez dans votre application. Cette ligne dans votre application ajoute un paramètre NVARCHAR :

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

tandis que dans le script SSMS vous le déclarez comme VARCHAR :

declare @clientID varchar(200)

En raison des règles de priorité des types de données, le Where client_id = @clientID l'expression dans votre requête n'est pas SARG-able où @clientID est de type NVARCHAR (je fais un acte de foi et suppose que client_id colonne est de type VARCHAR). L'application force ainsi une analyse de table où la requête SSMS peut effectuer une recherche rapide de clé. Il s'agit d'un problème bien connu et compris avec l'utilisation de Parameters.AddWithValue et a été discuté dans de nombreux articles auparavant, par exemple. voir Comment le code d'accès aux données affecte les performances de la base de données. Une fois le problème compris, les solutions sont triviales :

  • ajoutez des paramètres avec le constructeur qui accepte un type :Parameters.Add("@clientID", SqlDbType.Varchar, 200) (et faire transmettre la longueur explicite pour éviter la pollution du cache, voir Performances des requêtes et planifier les problèmes de cache lorsque la longueur du paramètre n'est pas spécifiée correctement

  • ou castez le paramètre dans le texte SQL :where client_id = cast(@clientID as varchar(200)) .

La première solution est supérieure car elle résout le problème de pollution du cache en plus du problème de capacité SARG.

Je vous recommande également de lire Slow in the Application, Fast in SSMS ? Comprendre les mystères des performances