views:

551

answers:

4

I have a junction table in my SQL Server 2005 database that consist of two columns:

  • object_id (uniqueidentifier)

  • property_id (integer)

These values together make a compound primary key.

What's the best way to create this PK index for SELECT performance?

If the columns were two integers, I would just use a compound clustered index (the default). However, I've heard bad things about clustered indexes when uniqueidentifiers are involved.

Anyone have experience with this situation?

+2  A: 

Yes, GUID's are really bad for clustered indexes, since the GUIDs is by design very random and thus leads to massive fragmentation and thus performance problems.

See Kim Tripp's blog - most notably "The CLustered Index Debate continues" and "GUIDs as PRIMARY and/or CLUSTERED key" - for a lot of valuable background info.

If you really need to have an index on these TWO columns, I'd suggest a non-clustered index - it can be a primary index - just better not a clustered index.

Marc

marc_s
There is an option to use a sequential guid (newsequentialID, it does have limitations as you can't call it directly as a function.) as Marc_s has stated its a bad idea as its will be included in any non clustered keys.
GrumpyMonkey
A: 

I i would create an identity column & then make this your primary key & clustered index. You can then create non clustered indexes on objectid propertyid as needed.

You can create a unique constraint to ensure uniqueness of your key.

The reason for this is that the rows will be inserted sequentially, so your reducing page splits. in addition using an integer for your PK means you have a smaller value for your clustered index.

Nick Kavadias
There must be a unique constraint on ObjectID and PropertyID - if that requires an index, so be it.
Jonathan Leffler
A: 

One alternative is to use what is known as a surrogate key (which incidentally can also be assigned as the primary key).

For example, adding an identity column that can be used to uniquely identify each row within the table i.e. a primary key.

Understand that a GUID is used to identify a record globally within SQL Server (which arguably is not a relationally correct practice however that is not a concern for us here).

The identity column, now also a primary key can/will have a clustered index applied. A separate, nonclustered index can then be applied to the compound key described by the original poster.

This practice avoids the issue of frequent page splits occurring within the clustered index (inserts into a random GUID primary key) as well as producing a smaller and more efficient clustered index, whilst also preserving the relationships defined within the database.

Surrogate Key Definition: http://en.wikipedia.org/wiki/Surrogate_key

John Sansom
A: 

Please refer to my blog article on an alternative approach to primary key GUIDs.

Jeff Ficher