33

I am creating a new database for a web site using SQL Server 2005 (possibly SQL Server 2008 in the near future). As an application developer, I've seen many databases that use an integer (or bigint, etc.) for an ID field of a table that will be used for relationships. But lately I've also seen databases that use the unique identifier (GUID) for an ID field.

My question is whether one has an advantage over the other? Will integer fields be faster for querying and joining, etc.?

UPDATE: To make it clear, this is for a primary key in the tables.

abatishchev
  • 92,232
  • 78
  • 284
  • 421
mkchandler
  • 4,318
  • 3
  • 19
  • 24
  • 6
    If the performance of int vs. GUID is a major contributing source of concern for your data bottleneck, consider yourself **very** fortunate. Most other applications run into other more pressing issues before this becomes a factor. – Joe Chung Jul 20 '09 at 04:23
  • 4
    Also, GUID's can be useful when doing Insert statements, since you can create your GUID in C# per se, then just do the insert and not have to wait for the database to return you the new identifier. – Jack Marchetti Jul 20 '09 at 12:56
  • @Joe Chung There is no performance issue right now, because the database is still being designed. – mkchandler Jul 20 '09 at 13:14

6 Answers6

53

GUIDs are problematic as clustered keys because of the high randomness. This issue was addressed by Paul Randal in the last Technet Magazine Q&A column: I'd like to use a GUID as the clustered index key, but the others are arguing that it can lead to performance issues with indexes. Is this true and, if so, can you explain why?

Now bear in mind that the discussion is specifically about clustered indexes. You say you want to use the column as 'ID', that is unclear if you mean it as clustered key or just primary key. Typically the two overlap, so I'll assume you want to use it as clustered index. The reasons why that is a poor choice are explained in the link to the article I mentioned above.

For non clustered indexes GUIDs still have some issues, but not nearly as big as when they are the leftmost clustered key of the table. Again, the randomness of GUIDs introduces page splits and fragmentation, be it at the non-clustered index level only (a much smaller problem).

There are many urban legends surrounding the GUID usage that condemn them based on their size (16 bytes) compared to an int (4 bytes) and promise horrible performance doom if they are used. This is slightly exaggerated. A key of size 16 can be a very peformant key still, on a properly designed data model. While is true that being 4 times as big as a int results in more a lower density non-leaf pages in indexes, this is not a real concern for the vast majority of tables. The b-tree structure is a naturally well balanced tree and the depth of tree traversal is seldom an issue, so seeking a value based on GUID key as opposed to a INT key is similar in performance. A leaf-page traversal (ie. a table scan) does not look at the non-leaf pages, and the impact of GUID size on the page size is typically quite small, as the record itself is significantly larger than the extra 12 bytes introduced by the GUID. So I'd take the hear-say advice based on 'is 16 bytes vs. 4' with a, rather large, grain of salt. Analyze on individual case by case and decide if the size impact makes a real difference: how many other columns are in the table (ie. how much impact has the GUID size on the leaf pages) and how many references are using it (ie. how many other tables will increase because of the fact they need to store a larger foreign key).

I'm calling out all these details in a sort of makeshift defense of GUIDs because they been getting a lot of bad press lately and some is undeserved. They have their merits and are indispensable in any distributed system (the moment you're talking data movement, be it via replication or sync framework or whatever). I've seen bad decisions being made out based on the GUID bad reputation when they were shun without proper consideration. But is true, if you have to use a GUID as clustered key, make sure you address the randomness issue: use sequential guids when possible.

And finally, to answer your question: if you don't have a specific reason to use GUIDs, use INTs.

Jim G.
  • 14,056
  • 19
  • 94
  • 153
Remus Rusanu
  • 273,340
  • 38
  • 408
  • 539
  • This is for use as a primary key in the tables I mentioned. – mkchandler Jul 20 '09 at 13:20
  • 2
    Use NEWSEQUENTIALID() if you have a clustered index. – James Westgate Nov 02 '15 at 11:44
  • @Reemus I understood until the last sentence. Why would you not use a GUID if they are similar? The first part of your answer made me think all was ok with them, but at the end I am not sure. Is it because tables with INTs might have the same value somewhere? – johnny Jan 03 '18 at 18:09
  • The specific reason to use GUIDs are: 1) they are client side generated (before insert), by multiple clients or 2) they will later be merged into a consolidated database. For both cases, the true randomness of GUIDs solves the uniqueness problem and the increased size is an acceptable trade-off. – Remus Rusanu Jan 03 '18 at 18:24
  • So you mean multiple clients, application, database, etc., that might have the same PK but for whatever reason, they now all need to be in the same database. – johnny Jan 03 '18 at 19:35
8

The GUID is going to take up more space and be slower than an int - even if you use the newsequentialid() function. If you are going to do replication or use the sync framework you pretty much have to use a guid.

JBrooks
  • 9,241
  • 2
  • 23
  • 29
6

INTs are 4 bytes, BIGINTs ar 8 bytes, and GUIDS are 16 bytes. The more space required to represent the data, the more resources required to process it -- disk space, memory, etc. So (a) they're slower, but (b) this probably only matters if volume is an issue (millions of rows, or thousands of transactions in very, very little time.)

The advantage of GUIDs is that they are (pretty much) Globally Unique. Generate a guid using the proper algorithm (and SQL Server xxxx will use the proper algorithm), and no two guids will ever be alike--no matter how many computers you have generating them, no matter how frequently. (This does not apply after 72 years of usage--I forget the details.)

If you need unique identifiers generated across multiple servers, GUIDs may be useful. If you need mondo perforance and under 2 billion values, ints are probably fine. Lastly and perhaps most importantly, if your data has natural keys, stick with them and forget the surrogate values.

Philip Kelley
  • 37,039
  • 10
  • 52
  • 87
4

if you positively, absolutely have to have a unique ID, then GUID. Meaning if you're ever gonna merge, sync, replicate, you probably should use a GUID.

For less robust things, an int, should suffice depending upon how large the table will grow.

As in most cases, the proper answer is, it depends.

Jack Marchetti
  • 15,026
  • 13
  • 73
  • 116
3

Use them for replication etc, not as primary keys.

Kimberly L Tripp article

  • Against: Space, not strictly monotonic, page splits, bookmark/RIDs etc
  • For: er...
gbn
  • 394,550
  • 75
  • 549
  • 647
2

Fully agreed with JBrooks. I want to say that when your table is large, and you use selects with JOINS, especially with derived tables, using GUIDs can significally decrease performance.

Alex_L
  • 2,598
  • 1
  • 13
  • 12