I have an Sql query that looks up a person based on SSN and returns the PersonID (identity column). There is a index on the SSN column in the persons table.
I have a
Check the type of parameter (@SSN) you pass to SQL. More often than not the parameter is added like this:
List<...> GetBySSN(string ssn) {
SqlCommand cmd = new SqlCommand (@"select ... from ... where SSN=@SSN", conn);
cmd.Parameters.AddWithValue("@SSN", ssn);
using (SqlDataReader rdr = cmd.ExecuteQuery()) {
...
}
}
This pattern unfortunately adds the @SSN
parameter as a NVARCHAR
type (ie. Unicode). The rules of SQL Server Data Type Precedence require the comparison between a NVARCHAR and a VARCHAR to be done as NVARCHAR, so the query is executed as if the following SQL was requested:
select ... from ... where CAST(SSN as NVARCHAR) = @SSN;
This query cannot benefit from an index on the SSN column so a table scan is performed instead. 90% of the times I investigate the claim 'the query runs slow from app but fast from SSMS' is this problem, because the vast majority of developers actually run a different query in SSMS to compare with (they use a VARCHAR argument or a hard coded value).
If this is indeed the problem, the solution is trivial: explicitly specify the parameter type as SqlDbType.VarChar.