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

.NET-Datenbankaufrufe langsam bei Verwendung von COM Interop, schnell über den Abfrageanalysator

Überprüfen Sie den Typ des Parameters (@SSN), den Sie an SQL übergeben. Meistens wird der Parameter wie folgt hinzugefügt:

List<...> GetBySSN(string ssn) {
   SqlCommand cmd = new SqlCommand (@"select ... from ... where [email protected]", conn);
   cmd.Parameters.AddWithValue("@SSN", ssn);
   using (SqlDataReader rdr = cmd.ExecuteQuery()) {
     ...
   }
}

Dieses Muster fügt leider den @SSN hinzu Parameter als NVARCHAR Typ (d. h. Unicode). Die Regeln von SQL Server Priorität der Datentypen erfordern, dass der Vergleich zwischen einem NVARCHAR und einem VARCHAR als NVARCHAR durchgeführt wird, sodass die Abfrage so ausgeführt wird, als ob die folgende SQL angefordert wurde:

select ... from ... where CAST(SSN as NVARCHAR) = @SSN;

Diese Abfrage kann nicht von einem Index für die SSN-Spalte profitieren, daher wird stattdessen ein Tabellenscan durchgeführt. In 90 % der Fälle, in denen ich die Behauptung „die Abfrage läuft langsam von der App, aber schnell von SSMS“ untersuche, ist dieses Problem, weil die überwiegende Mehrheit der Entwickler tatsächlich eine andere ausführt Abfrage in SSMS zum Vergleichen (sie verwenden ein VARCHAR-Argument oder einen hartcodierten Wert).

Wenn dies tatsächlich das Problem ist, ist die Lösung trivial:Spezifizieren Sie den Parametertyp explizit als SqlDbType.VarChar .