DOWNLOAD THE CODE:
Download the Code 99148.zip

6. Wasted Network Bandwidth
SQL Server’s default behavior is to constantly update clients about current execution status while a query, batch, or operation is being processed. Although beneficial in some cases, this chattiness adds additional network overhead. Therefore a good rule of thumb is to ensure that stored procedures called by applications take advantage of the SET NOCOUNT ON directive to turn off status messages. Doing so can cut back significantly on network traffic and, in the words of SQL Server Books Online (BOL), “provide a significant performance boost.” Web Listing 2 shows an example of using SET NOCOUNT on.

In a similar vein, developers should also avoid SELECT * queries when returning result sets, as these result sets typically return much more data than the calling application needs. Therefore, a great way to optimize code is to make sure that you’re returning only columns that you need; failing to do so results in additional network overhead with no benefits. Likewise, another good rule of thumb is to try to always horizontally restrict returned data to only what’s needed (through efficient use of the WHERE clause).

7. Improper Use of Cursors
Sadly, cursors are prone to abuse. But as long as cursor-based operations aren’t causing massive performance problems (or can’t be easily rewritten using set-based logic), I typically encourage clients to use optimized declaration syntax and ensure that cursors are closed and de-allocated as soon as possible. A key consideration that makes this recommendation possible is the fact that most developers intend to use lightweight, single-direction cursors for simple looping operations. However, although this might be their intention in most cases, developers will end up with a much more expensive cursor unless they use very explicit syntax.

The fix for this problem is usually simple: Use more verbose syntax (as Listing 3 shows). By explicitly declaring lightweight cursors designed for use by the current connection only, and by ensuring that cursors are closed and de-allocated (especially when nested) as soon as possible, you can overcome many of the problems typically associated with cursors without spending a lot of development effort.

8. Failure to Use Full-Text Indexing
In cases where SARGable queries aren’t possible due to a requirement to search for %conditions% in the middle text columns, full-text indexing can be a lifesaver. Without full-text indexing, the best you can hope for is an index scan (which requires less I/O than a full table scan). But against millions of rows, even an index scan can gobble up excessive amounts of CPU resource, which can adversely impact systemwide performance.

By tokenizing text data with a full-text index, not only can you drastically decrease the size of the indexes used for queries, but SQL Server can provide results much closer to those you’d anticipate with an index seek. The result is that, in certain scenarios, full-text indexing can yield queries that require substantially less processing and return results at a fraction of the cost imposed by their traditional counterparts. For example, the data in Figure 2, page 16, was taken from an environment where more than 8 million rows were being pummeled up to 12 times a second by a fairly complex query.

Best of all, these improvements can also free up existing I/O and CPU resources—which translates to better overall system performance. Therefore, although full-text indexing can’t solve every problem, you should evaluate it as a possible way to boost performance if you’re doing intensive text searches. There’s also a slight performance hit involved with turning full-text indexing on, so make sure you’re getting tangible benefits by going this route.

9. Failure to Use Multiple Data Files
A key performance enhancement that many organizations fail to take advantage of is SQL Server’s support for multiple data files. In scenarios in which a database is larger than the amount of physical memory available, consider using multiple data files, especially if the server in question has multiple processors and one or more RAID controllers. Furthermore, the benefits of using multiple data files are even more pronounced in cases where most of the database’s data is housed in a handful of heavily used tables. Finding the right number of data files to use can require some testing, but as long as you don’t go crazy adding secondary data (.ndf) files, it’s hard to go wrong. In fact, Microsoft recommends a ratio of roughly 0.25 to 1 data file per file group per processor. Why? Because adding more files lets SQL Server take advantage of parallel processing by delegating expensive read operations to dedicated I/O threads. The more threads—up to a point—the better. Therefore, moving a heavily used table to a dedicated file group, and its nonclustered indexes to another dedicated file group, can provide serious performance benefits—especially if you can place the files for these file groups on different physical disk arrays or spindles.

10. Failure to Properly Size Data Types
Failure to properly size data types can result in costly performance problems that can be difficult to diagnose and correct. This problem partly stems from the fact that many developers don’t realize that as far as SQL Server is concerned, a VARCHAR(20) is a different data type than a VARCHAR(30). Throwing NVARCHAR versus VARCHAR and NULL versus NOT NULL into the mix only complicates things further. Masking the problem, however, is the fact that SQL Server typically handles subtle differences by transparently converting one data type to another in most cases.

Where this can cause problems, however, is when coercion causes SQL Server to choose an index or table scan instead of a much better-performing index seek. On smaller tables, these effects are typically negligible; however, as tables begin to grow, the effect can become much more pronounced. In some cases, this means that coercion can be a “silent thief” that slows moderately sized queries to a degree that usually goes unnoticed. However, in extreme cases, I’ve seen examples where a stored procedure declared an NVARCHAR(50) parameter and used it in a WHERE clause against a VARCHAR(50) column, which resulted in an index scan that was making the query take four seconds to execute. By simply changing the parameter to match the table’s data type, SQL Server was able to revert to an index seek that completed in milliseconds. Therefore, although the frequency of performance issues caused by this problem is typically very low, it’s always a good idea to pay close attention to data-type declarations and sizing when coding to avoid having your code become a sad statistic in the war on optimizing database performance.

Performance Considerations
Optimizing SQL Server performance is a vast topic that you can approach from many different angles. This article focuses on a smattering of common problems that are typically fairly easy to remedy. My hunch is that most SQL Server deployments suffer from a handful of issues outlined in this article—but it’s my hope that this article has also gotten you to think a bit more about ways to tackle performance issues while you code, rather than after the fact.

End of Article

Prev. page     1 [2]     next page -->



You must log on before posting a comment.

If you don't have a username & password, please register now.

Reader Comments

As a long-time SQL Server consultant, I like this article because it describes the same things I see every day. However, I have to take exception to some of the things said about AWE memory.

In that discussion there seems to be some confusion between physical memory and virtual address space. As I understand it and as the URLs below will confirm, AWE is irrelevant unless a machine has more that 4GB of RAM, not 2GB as implied here. I have seen the web page to which this article refers and it puzzles me. It contradicts everything else that Microsoft and others have published about AWE from day 1.

The default size of the user-mode portion of the 4GB virtual address space is 2GB and that may be the source of the confusion. The kernel-mode processes occupy the other 2GB. On a machine with 4GB of RAM you can expand the user-made address space to 3GB of the total 4GB (VAS, not RAM) with the /3GB switch in boot.ini, but that has nothing to do with AWE.

I know that there is a lot of disinformation, partial information, and outright wrong information on this topic. Most of it springs from a confusion between physical memory and virtual address space. However, I may have absorbed some of that disinformation too, but I have configured AWE on many,many systems and it worked fine. I have to admit I never tried enabling AWE on a system with less than 4GB because there seemed to be no point since any 32bit process can access 4GB of RAM without AWE. /#GB makes sense on a 4GB system, but not AWE.

The article also does not mention that AWE is only for the 32bit OS and does not mention the OS set up that needs to be done before any of this will work.

here are two of the hundreds of urls that will also affirm that AWE is only necessary in 32bit systems with more than 4GB of RAM. http://technet.microsoft.com/en-us/library/ms175581.aspx http://technet.microsoft.com/en-us/library/ms179301.aspx

Regards,

Kurt Survance

ksurvance

Article Rating 3 out of 5

Hi Michael, I'm not sure if your article specifically recommend to allocate to create 0.25 to 1 data file per filegroup per processor (point 9). If yes, I dont think i would agree with it as I feel this recommendation is only contained to tempdb.

PSS has specifically mention in their article stating this recommendation is not for user database as it does not usually have DDL contention, unless for whatever reason you're creating/dropping too many temp tables on your user database.

http://blogs.msdn.com/psssql/archive/2007/02/21/sql-server-urban-legends-discussed.aspx

Most people have this misconception of a worker allocated per data file in sql. Actually, this one worker per data file is i.e. when you create database different drive, hence, workers do the creation so the database may be created faster due to parallel work streams.

Please comment and reply to me on your thoughts.

Regards, Garry

garry.mortimer@btfinancialgroup.com

Article Rating 2 out of 5

Kurt,

Check out this article: http://technet.microsoft.com/en-us/library/ms190673.aspx

Where there are a couple of cases where MS points out that AWE can, indeed, address physical memory below the 4GB limit (and above the 2GB non-AWE window).

Here's a quote: Since AWE-mapped memory is supported below 3 GB, you can define the min server memory and max server memory values within the physical memory range, or use the default values for both options.

This article also points out that you can configure AWE on systems where the OS LIMITS you to only 4GB - which infers that you could (and would want to) set AWE on systems with as 'little' as 4GB of physical RAM.

That said, I agree - this is one of the most confusing aspects of SQL Server management and configuration. It's also worth pointing out that in the article I was really only talking about cases where I come in to an environment where there's some beefy hardware and can spot that AWE isn't configured correctly because task manager is only showing just under 2GB of RAM being used. In other words, I wasn't talking about setting AWE in those 2-4GB ranges either.

And um, cough, since I have to rate the article to submit comments... I'll um... rate it as a 5 /5 *grin*

overachiever

Article Rating 5 out of 5

Gary,

You are correct - that .25/processor ratio is specifically for the tempDB, otherwise the 1/processor applies to user DBs. Sadly, given the tiny bit of space I had to work with, I just had to say .25-1/processor to be 'all inclusive'. Interestingly enough, I THOUGHT I had a link to that EXACT PSS post in my article.

That said... I've also written another article focusing solely on improving IO performance that should be getting published... .sometime soon - where I deal with this just a bit more.

--Mike www.sqlservervideos.com

overachiever

Article Rating 5 out of 5

 
 

ADS BY GOOGLE