Login or Sign Up to become a member!
LessThanDot Sit Logo

LessThanDot

Data Management

Less Than Dot is a community of passionate IT professionals and enthusiasts dedicated to sharing technical knowledge, experience, and assistance. Inside you will find reference materials, interesting technical discussions, and expert tips and commentary. Once you register for an account you will have immediate access to the forums and all past articles and commentaries.

LTD Social Sitings

Lessthandot twitter Lessthandot Linkedin Lessthandot friendfeed Lessthandot facebook Lessthandot rss

Note: Watch for social icons on posts by your favorite authors to follow their postings on these and other social sites.

Your profile

Authors

Search

XML Feeds

Google Ads

« Best Practice: Coding SQL Server triggers for multi-row operationsSSRS 2005 Matrixes »
comments
Rate Post:
submit to reddit Digg!FacebookDotnetkicks

There can only be one clustered index per table because SQL Server stores the data in the table in the order of the clustered index . When you use a UniqueIdentifier as the first column in a clustered index, every time you insert a row in the table, it is almost guaranteed to be inserted in to the middle of the table. SQL server stores data in 8K pages. If a page is full, SQL Server will do a page split, which causes another 8k page to be allocated and half the data from the previous page to be moved to the new page. Individually, each page split is fast but does take a little bit of time. In a high transaction environment, there could be many page splits happening frequently, which ultimately result in slower performance.

When you use an Identity column for a clustered index, the next value inserted is guaranteed to be higher than the previous value. This means that new rows will always be added to the end of the table and you will not get unnecessary page splits for table fragmentation.

SQL Server 2005 introduced a new function called NewSequentialId(). This function can only be used as a default for a column of type UniqueIdentifier. The benefit of NewSequentialId is that it always generates a value greater than any other value already in the table. This causes the new row to be inserted at the end of the table and therefore no page splits.

How to detect this problem:

  1. SELECT  so.name AS TableName,
  2.         sind.name AS IndexName,
  3.         sik.keyno,
  4.         col.name AS ColName,
  5.         systypes.name,
  6.         sind.OrigFillFactor,
  7.         syscomments.TEXT AS ColumnDefault
  8. FROM    sysobjects so
  9.         INNER join sysindexes sind
  10.           ON so.id=sind.id
  11.         INNER join sysindexkeys sik
  12.           ON sind.id=sik.id
  13.           and sind.indid=sik.indid
  14.         INNER join syscolumns col
  15.           ON col.id=sik.id
  16.           and col.colid=sik.colid
  17.         INNER join systypes
  18.           ON col.xtype = systypes.xtype
  19.         INNER join syscomments
  20.           ON col.cdefault = syscomments.id
  21. WHERE   sind.status & 16 = 16
  22.         and systypes.name = 'uniqueidentifier'
  23.         and keyno = 1
  24.         and sind.OrigFillFactor = 0
  25.         and syscomments.TEXT Like '%newid%'
  26. ORDER BY so.name, sik.keyno

How to correct it: There are several ways to prevent this problem. The best method is to use NewSequentialId() instead of NewId. Alternatively (if you are using SQL 2000), you could set the fill factor for the index to be less than 100%. Fill factor identifies how "full" the data pages are when you recreate the index. With a 100% fill factor there is no room in the index to accommodate new rows. If you need to use a UniqueIdentifier, and it must be clustered and you cannot use NewSequentialId, then you should modify the Fill Factor to minimize page splits. If you do this, it's important to rebuild the index periodically.

Level of severity: Moderate

Level of difficulty: Easy

About the Author

George has been developing software professionally for 19 years, first for the department of defense, and then for various other companies. In 1998, George started his software company, Orbit Software, specializing in School Bus Transportation software. His specialty is refining SQL Server queries to deliver optimal performance.
Social SitingsTwitterLTD RSS Feed
285 views
submit to reddit Digg!FacebookDotnetkicks

Comments and Feedback

1 comment

Comment from: thirster42 [Member] Email
Very informative. I never would have known about this, although I rarely use uids.
11/12/09 @ 07:18

Leave a comment


Your email address will not be revealed on this site.

Your URL will be displayed.
(Line breaks become <br />)
(Name, email & website)
(Allow users to contact you through a message form (your email will not be revealed.)