Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should a Composite Primary Key be clustered in SQL Server?

Consider this example table (assuming SQL Server 2005):

create table product_bill_of_materials
(
    parent_product_id int not null,
    child_product_id int not null,
    quantity int not null
)

I'm considering a composite primary key containing the two product_id columns (I'll definitely want a unique constraint) as opposed to a separate unique ID column. Question is, from a performance point of view, should that primary key be clustered?

Should I also create an index on each ID column so that lookups for the foreign keys are faster? I believe this table is going to get hit much more on reads than writes.

like image 383
Neil Barnwell Avatar asked Dec 23 '08 16:12

Neil Barnwell


People also ask

Can composite primary key be clustered?

If you are creating a composite Primary Key, or a composite Clustered Index that is NOT a Primary Key, you are creating a single index that uses both column values as the clustering key. There is only one Clustered Index!

Can composite key be clustered index?

Primary Keys of the table by default are clustered index. Composite key when used with unique constraints of the table act as non-clustered index.

Should primary key be clustered?

The PRIMARY KEY does not have to be CLUSTERED.

Does primary key have to be clustered index?

PRIMARY KEY and UNIQUE constraints When you create a PRIMARY KEY constraint, a unique clustered index on the column or columns is automatically created if a clustered index on the table does not already exist and you do not specify a unique nonclustered index. The primary key column cannot allow NULL values.


1 Answers

As has already been said by several others, it depends on how you will access the table. Keep in mind though, that any RDBMS out there should be able to use the clustered index for searching by a single column as long as that column appears first. For example, if your clustered index is on (parent_id, child_id) you don't need another separate index on (parent_id).

Your best bet may be a clustered index on (parent_id, child_id), which also happens to be the primary key, with a separate non-clustered index on (child_id).

Ultimately, indexing should be addressed after you've got an idea of how the database will be accessed. Come up with some standard performance stress tests if you can and then analyze the behavior using a profiling tool (SQL Profiler for SQL Server) and performance tune from there. If you don't have the expertise or knowledge to do that ahead of time, then try for a (hopefully limited) release of the application, collect the performance metrics, and see where you need to improve performance and figure out what indexes will help.

If you do things right, you should be able to capture the "typical" profile of how the database is accessed and you can then rerun that over and over again on a test server as you try various indexing approaches.

In your case I would probably just put a clustered PK on (parent_id, child_id) to start with and then add the non-clustered index only if I saw a performance problem that would be helped by it.

like image 86
Tom H Avatar answered Oct 14 '22 02:10

Tom H