Av rating:
Total votes: 61
Total comments: 13


Andy Warren
Performance tuning tips for database developers
17 May 2005

Performance tuning is not easy and there aren’t any silver bullets, but you can go a surprisingly long way with a few basic guidelines.

In theory, performance tuning is done by a DBA. But in practice, the DBA is not going to have time to scrutinize every change made to a stored procedure. Learning to do basic tuning might save you from reworking code late in the game.

Below is my list of the top 15 things I believe developers should do as a matter of course to tune performance when coding. These are the low hanging fruit of SQL Server performance – they are easy to do and often have a substantial impact. Doing these won’t guarantee lightening fast performance, but it won’t be slow either.

  1. Create a primary key on each table you create and unless you are really knowledgeable enough to figure out a better plan, make it the clustered index (note that if you set the primary key in Enterprise Manager it will cluster it by default).
  2. Create an index on any column that is a foreign key. If you know it will be unique, set the flag to force the index to be unique.
  3. Don’t index anything else (yet).
  4. Unless you need a different behaviour, always owner qualify your objects when you reference them in TSQL. Use dbo.sysdatabases instead of just sysdatabases.
  5. Use set nocount on at the top of each stored procedure (and set nocount off) at the bottom.
  6. Think hard about locking. If you’re not writing banking software, would it matter that you take a chance on a dirty read? You can use the NOLOCK hint, but it’s often easier to use SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED at the top of the procedure, then reset to READ COMMITTED at the bottom.
  7. I know you’ve heard it a million times, but only return the columns and the rows you need.
  8. Use transactions when appropriate, but allow zero user interaction while the transaction is in progress. I try to do all my transactions inside a stored procedure.
  9. Avoid temp tables as much as you can, but if you need a temp table, create it explicitly using Create Table #temp.
  10. Avoid NOT IN, instead use a left outer join - even though it’s often easier to visualize the NOT IN.
  11. If you insist on using dynamic sql (executing a concatenated string), use named parameters and sp_executesql (rather than EXEC) so you have a chance of reusing the query plan. While it’s simplistic to say that stored procedures are always the right answer, it’s also close enough that you won’t go wrong using them.
  12. Get in the habit of profiling your code before and after each change. While you should keep in mind the depth of the change, if you see more than a 10-15% increase in CPU, Reads, or Writes it probably needs to be reviewed.
  13. Look for every possible way to reduce the number of round trips to the server. Returning multiple resultsets is one way to do this.
  14. Avoid index and join hints.
  15. When you’re done coding, set Profiler to monitor statements from your machine only, then run through the application from start to finish once. Take a look at the number of reads and writes, and the number of calls to the server. See anything that looks unusual? It’s not uncommon to see calls to procedures that are no longer used, or to see duplicate calls. Impress your DBA by asking him to review those results with you.

If you take these 15 steps, you’ve made a really good first pass.

There’s more to learn next time as we build a model of how your application, the network, and SQL Server all offer the potential for bottlenecks. We will also look at the potential for improving performance and some more steps that you can take without stepping too far into the land of the DBA.



This article has been viewed 9860 times.
Andy Warren

Author profile: Andy Warren

Andy Warren is a SQL Server guru and regular columnist for SQL Server Central.com. He can be reached at awarren@sqlservercentral.com.

Search for other articles by Andy Warren

Rate this article:   Avg rating: from a total of 61 votes.


Poor

OK

Good

Great

Must read
 
Have Your Say
Do you have an opinion on this article? Then add your comment below:
You must be logged in to post to this forum

Click here to log in.


Subject: Greet article
Posted by: moh hassan (not signed in)
Posted on: Wednesday, January 10, 2007 at 12:54 AM
Message: Greet article for Performance tuning tips

Subject: Good help ..
Posted by: Anonymous (not signed in)
Posted on: Sunday, January 28, 2007 at 11:31 PM
Message: Hi ,
this really a good article ..
Looing forward for the next which will elaborate more advanced tips...

Subject: Great Tips
Posted by: Jayesh (not signed in)
Posted on: Wednesday, June 13, 2007 at 1:22 AM
Message: Andy,

Great work.


Subject: GooD Job
Posted by: mega5357 (view profile)
Posted on: Thursday, June 28, 2007 at 11:37 PM
Message: thanks buddy

Subject: hmmm...
Posted by: Anonymous (not signed in)
Posted on: Friday, July 06, 2007 at 2:20 PM
Message: disagree with you on several points, but its OK:) most are good.

Temp tables are better for certain issues over derived or table variables. Table variables can cause issues in 2005 also.

If you have to use nolock, fire your DBA, he is not doing his job.

#13 is a good case for a temp table.. add an index too!

and of course.. if you are tuning in a DEV environment ONLY do:

DBCC FREEPROCCACHE --(to clear plans from cache)
DBCC DROPCLEANBUFFERS --(to clear data from cache)

else your results will be misleading. dont forget to remove that.. never do those commands on a prod box.

Not in can be alot better than left outer joins. I had one recently where I did left outers on derived tables which took several minutes to run. took those selects from the derrived and put them into temp tables then left outer joined them and still took several minutes. did several "not ins" with those temp tables and it took < 1 second. It is all dependant on the situation.

Subject: hmmm...corrected....
Posted by: Anonymous (not signed in)
Posted on: Friday, July 06, 2007 at 2:21 PM
Message: reorg....

disagree with you on several points, but its OK:) most are good.

Temp tables are better for certain issues over derived or table variables. Table variables can cause issues in 2005 also.

"Not in" can be alot better than left outer joins. I had one recently where I did left outers on derived tables which took several minutes to run. took those selects from the derrived and put them into temp tables then left outer joined them and still took several minutes. did several "not ins" with those temp tables and it took < 1 second. It is all dependant on the situation.

If you have to use nolock, fire your DBA, he is not doing his job.

#13 is a good case for a temp table.. add an index too!

and of course.. if you are tuning in a DEV environment ONLY do:

DBCC FREEPROCCACHE --(to clear plans from cache)
DBCC DROPCLEANBUFFERS --(to clear data from cache)

else your results will be misleading. dont forget to remove that.. never do those commands on a prod box.


Subject: hmmm...corrected....
Posted by: Anonymous (not signed in)
Posted on: Friday, July 06, 2007 at 2:43 PM
Message: reorg....

disagree with you on several points, but its OK:) most are good.

Temp tables are better for certain issues over derived or table variables. Table variables can cause issues in 2005 also.

"Not in" can be alot better than left outer joins. I had one recently where I did left outers on derived tables which took several minutes to run. took those selects from the derrived and put them into temp tables then left outer joined them and still took several minutes. did several "not ins" with those temp tables and it took < 1 second. It is all dependant on the situation.

If you have to use nolock, fire your DBA, he is not doing his job.

#13 is a good case for a temp table.. add an index too!

and of course.. if you are tuning in a DEV environment ONLY do:

DBCC FREEPROCCACHE --(to clear plans from cache)
DBCC DROPCLEANBUFFERS --(to clear data from cache)

else your results will be misleading. dont forget to remove that.. never do those commands on a prod box.


Subject: Where?
Posted by: Anonymous (not signed in)
Posted on: Monday, March 03, 2008 at 10:24 PM
Message: Where is the other artile mate?

Subject: tks
Posted by: Georges (not signed in)
Posted on: Wednesday, May 07, 2008 at 1:32 PM
Message: it's helping me out to improve my stuffs!
Tks a lot

Subject: j
Posted by: Anonymous (not signed in)
Posted on: Tuesday, June 17, 2008 at 4:06 AM
Message: j

Subject: What is the disadvantage of WITH (NOLOCK)
Posted by: Smith (not signed in)
Posted on: Tuesday, June 17, 2008 at 4:09 AM
Message: Hi All

If we use WITH (NOLOCK) with the temp table then what will be the impact of this on the performance. Is it advisable to put WITH (NOLOCK) on temp table or not. For Example :-

Select * from #temptbl WITH (NOLOCK)

Thanks

Subject: What is the disadvantage of WITH (NOLOCK)
Posted by: Smith (not signed in)
Posted on: Tuesday, June 17, 2008 at 5:10 AM
Message: Hi All

If we use WITH (NOLOCK) with the temp table then what will be the impact of this on the performance. Is it advisable to put WITH (NOLOCK) on temp table or not. For Example :-

Select * from #temptbl WITH (NOLOCK)

Thanks

Subject: To aid Hmmmm. CorreTed..
Posted by: Anonymous (not signed in)
Posted on: Thursday, August 14, 2008 at 12:21 AM
Message: First, as a table hint (NOLOCK) the DBA has no control over sloppy developers who cause SQL to escalate the locks by requesting more data than necessary.
B. Creation of #myTempTable is enacted in tempDB and has the Scope of the calling procedure (Local) therefore (NOLOCK) on the #myTempTable has little or no benefit.

Just My Humble.....

 









Phil Factor
Bunnikins!
 When an IT manager is selected as a victim of office politics of a large corporate, it is time for him to engage in... Read more...



 View the blog
SQL Toolbelt 2008: Predominantly an Engineering Task
 The conversion of the Red-Gate tools to be compatible with SQL Server 2008 might not seem, on first... Read more...

Audit Crosschecks
 In this short article, the second of a 2-part series, William suggests a solution, using SQL Data... Read more...

Discovering Security Uses for SQL Compare
 Much of the security of SQL Server is implemented as part of the database schema. This provides some... Read more...

XML Jumpstart Workbench
 In which Robyn and Phil decide that the best way of starting to learn XML is to jump in and take a ride... Read more...

RSS Newsfeed Workbench
 Robyn and Phil decide to build an RSS newsfeed in TSQL, using the power of SQL Server's XML.  Read more...

Beginning SQL Server 2005 Reporting Services Part 1
 Steve Joubert begins an in-depth tour of SQL Server 2005 Reporting Services with a step-by-step guide... Read more...

Ten Common Database Design Mistakes
 Database design and implementation is the cornerstone of any data centric project (read 99.9% of... Read more...

SQL Server Full Text Search Language Features
 SQL Full-text Search (SQL FTS) is an optional component of SQL Server 7 and later, which allows fast... Read more...

Beginning SQL Server 2005 Reporting Services Part 2
 Continuing his in-depth tour of SQL Server 2005 Reporting Services, Steve Joubert demonstrates the most... Read more...

Executing SSIS Packages
 Nigel Rivett demonstrates how to execute all SSIS packages in a given folder using either an SSIS... Read more...

Over 150,000 Microsoft professionals subscribe to the Simple-Talk technical journal. Join today, it's fast, simple, free and secure.

Join Simple Talk