SQL: Improve Dynamic(Ad hoc) SQL Query Performance

Dynamic(Ad hoc) SQL query can be as performant as stored procedures if you use it correctly since SQL server can cache the compiled query plan and re-use 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 EmployeeTerritories 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 SQL server executes following statement:

   
    EXEC sp_executesql N'SELECT * FROM employees e INNER JOIN EmployeeTerritories 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 EmployeeTerritories 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 EmployeeTerritories 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 SQL statement parameterized.

See also

  • SQL: Use Dynamic SQL Query Correctly
  • SQL 2005: Use DMV and CROSS APPLY to Get Cached Plans
  • SQL 2005: Discontinued or Deprecated Features in SQL Server 2005
  • SQL 2005: Default Trace Enabled Option
  • SQL 2005: Column Level Permissions
  • SQL 2005: SQLCMD Supports Parameterized Variables and Macro Features
  • SQL 2005: DTS Has Become SSIS now
  • SQL 2005: Microsoft SQL Server 2005 JDBC Driver
  • SQL 2005: Query Notifications in ADO.Net 2.0
  • SQL 2005: Overcome SQL Index Size Limit
  • SQL 2005: DDL Triggers
  • SQL 2005: Why Should Use 64 Bit Now
  • SQL 2005: How to Rebuild The Master Database
  • SQL 2005: A Little Trick to Install SQL 2005 Onto Your Dirty DEV Machine
  • SQL 2005: New Resource Database
  • SQL 2005: Alter Index Rebuild
  • SQL 2005: XQuery Sample
  • SQL 2005: How to Move Database
  • SQL: Use COALESCE to Generate a List
  • SQL: How to Debug SQL Deadlocks
  • .Net: How to Bypass Strong Name Check
  • Agile: Lean Software Development - An Agile Toolkit
  • ORM: How to Use nHibernate 1.2 to Call Stored Procedure to Return a Dataset Without a Mapping Entity
  • AJAX: ASP.NET AJAX Tips
  • .Net: Debugging Commands
  • .Net: How to Run NUnit And Debug Your Test Fixtures Directly from VS 2005
  • .Net: How to Add Domain User to Local Group
  • .Net: Lock Value Type?
  • .Net: How to Create an Instance of a Generic Type with Parameters
  • .Net: How to Get Address of a Managed Type
  • ORM: New Features of nHibernate 1.2
  • .Net: How to Get System Error Message from HRESULT in Managed Code
  • .Net: Use Windows PowerShell Now
  • WMI: Use WMI to Run Commands on Remote Machine
  • API: GetLogicalProcessorInformation to Detect CPUs
  • .Net: How to Implement Singleton Correctly
  • .Net: There is no MTS object context (Exception from HRESULT: 0x8004E004)
  • .Net: The Net Objectives Pattern Repository
  • Web: Access Denied When ASP.Net Accesses Eventlog
  • Nant: Error Loading GUID of Project
  • AJAX: Ajax in Action
  • DTC: DtcGetTransactionManager Fails
  • .Net: Run .Net 1.1 COM+ Serviced Components Under .Net 2.0 Framework
  • .Net: Debugging Managed Code Tip
  • .Net: Assembly Binding Log Viewer (Fuslogvw.exe)
  • .Net: .Net Framework Design Guidelines
  • .Net: Use Global Catalog and CheckTokenMembership to Check AD Group Membership



  • THIS POST IS PROVIDED "AS-IS" WITH NO WARRANTIES AND CONFERS NO RIGHTS. Build time: Sun 03/30/2008 . ©2007 Dalun Software. All rights reserved. Back to Article List