Does SQL Server build an index on primary keys by default? If yes what kind of index? If no what kind of index is appropriate for selections by primary key?
I use SQL Server 2008 R2
Thank you.
A primary index is automatically created for the primary key and ensures that the primary key is unique. You can use the primary index to retrieve and access objects from the database. The unique index is a column, or an ordered collection of columns, for which each value identifies a unique row.
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.
This index measures the default rates across auto loans. It is included in the S&P/Experian Consumer Credit Default Index Series which seeks to measure the balance-weighted proportion of consumer credit accounts that go into default for the first time each month.
The primary key is the default clustered index in SQL Server and MySQL. This implies a 'clustered index penalty' on all non-clustered indexes.
You can easily determine the first part of this for yourself
create table x
(
id int primary key
)
select * from sys.indexes where object_id = object_id('x')
Gives
object_id name index_id type type_desc is_unique data_space_id ignore_dup_key is_primary_key is_unique_constraint fill_factor is_padded is_disabled is_hypothetical allow_row_locks allow_page_locks
1653580929 PK__x__6383C8BA 1 1 CLUSTERED 1 1 0 1 0 0 0 0 0 1 1
Edit: There is one other case I should have mentioned
create table t2 (id int not null, cx int)
create clustered index ixc on dbo.t2 (cx asc)
alter table dbo.t2 add constraint pk_t2 primary key (id)
select * from sys.indexes where object_id = object_id('t2')
Gives
object_id name index_id type type_desc is_unique data_space_id ignore_dup_key is_primary_key is_unique_constraint fill_factor is_padded is_disabled is_hypothetical allow_row_locks allow_page_locks has_filter filter_definition
----------- ------------------------------ ----------- ---- ------------------------------ --------- ------------- -------------- -------------- -------------------- ----------- --------- ----------- --------------- --------------- ---------------- ---------- ------------------------------
34099162 ixc 1 1 CLUSTERED 0 1 0 0 0 0 0 0 0 1 1 0 NULL
34099162 pk_t2 2 2 NONCLUSTERED 1 1 0 1 0 0 0 0 0 1 1 0 NULL
With regard to the second part there is no golden rule it depends on your individual query workload, and what your PK is.
For satisfying individual lookups by primary key a non clustered index will be fine. If you are doing queries against ranges these would be well served by a matching clustered index but a covering non clustered index could also suffice.
You also need to consider the index width of the clustered index in particular as it impacts all your non clustered indexes and effect of inserts on page splits.
I recommend the book SQL Server 2008 Query Performance Tuning Distilled to read more about the issues.
Yes. By default a unique clustered index is created on all primary keys, but you can create a unique nonclustered index instead of you like.
As to what the appropriate choice, I'd say that for 80-90% of the tables you create, you generally want the clustered index to be the primary key, but that's not always the case.
You'd typically make the clustered index something else if you do heavy range scans on that "something else". For example, if you have a synthetic primary key*, but have a date column that you typically query in terms of a range, you'd often want that date column to be the most significant column in your clustered index.
*That's usually done by using an INT IDENTITY column as the PK on the table.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With