NetInverse Developers Blog

March 5, 2009
Category: SQL — Tags: , , — admin @ 9:41 pm

Dynamic(Ad hoc) SQL query can be as performant as stored procedures if you use it correctly. SQL server compiles it, caches the compiled query plan and re-uses it next time. If not, SQL server may have to re-compile the query every time, and which can be sometimes 100 times slower!

For example:

     String query = @"SELECT *
                        FROM employees e
                  INNER JOIN EmployeeDetails et
                          ON e.employeeid = et.employeeid
                       WHERE e.employeeid = @id";

     sqlCmd.CommandType = System.Data.CommandType.Text;
     SqlParameter idParam = new SqlParameter(
         "@id", System.Data.SqlDbType.Int, 0);
     sqlCmd.Parameters.Add(idParam);
     sqlCmd.Parameters[0].Value = 100;
     sqlReader = sqCmd.ExecuteReader();

If you use SQL Tracer, you will see the SQL server executes following statement:

 EXEC sp_executesql N'SELECT * FROM employees e
 INNER JOIN EmployeeDetails et ON e.employeeid = ee.employeeid
 WHERE e.employeeid = @id', N'@id int',@id=100

In this case, SQL server can cache the query plan and re-used it effectively. Because the statement is parameterized, even the value of @id changes, the compiled statement remains same and can be always re-used.

A common mistake of using dynamic SQL is like below:

      String query = @"SELECT *
                         FROM employees e
                   INNER JOIN EmployeeDetails et
                           ON e.employeeid = ee.employeeid
                        WHERE e.employeeid = " + id.ToString();

     sqlCmd.CommandType = System.Data.CommandType.Text;
     sqlReader = sqCmd.ExecuteReader();

If you trace again, this time you will see SQL server executes the following instead:

 SELECT * FROM employees e INNER JOIN EmployeeDetails et
 ON e.employeeid = ee.employeeid WHERE e.employeeid = 100

SQL server can cache and re-use above statement as well. However, since the statement is not parameterized, if the
employeeid changes, SQL server will have to re-compile the statement. The consequence is low cache hit and SQL server will have a lot of recompiling, the overall performance will be poor.

So the take away here is, you can use dynamic SQL query, but do use SqlParameter to make your dynamic SQL statement parameterized.

©2009 NetInverse. All rights reserved. Powered by WordPress