Индекс по умолчанию для основного ключа

Создает ли SQL Server индекс первичных ключей по умолчанию? Если да, то какой индекс? Если какой-либо индекс не подходит для выбора с помощью первичного ключа?

Я использую SQL Server 2008 R2

Спасибо.

Ответ 1

Вы можете легко определить первую часть этого для себя

create table x
(
id int primary key
)

select * from sys.indexes where object_id = object_id('x')

дает

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

Изменить: Есть еще один случай, о котором я должен был упомянуть

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')

дает

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

Что касается второй части, то нет золотого правила, это зависит от вашей индивидуальной рабочей нагрузки запроса и от того, что ваш ПК.

Для удовлетворения индивидуального поиска по первичному ключу не кластеризованный индекс будет в порядке. Если вы выполняете запросы против диапазонов, это будет хорошо обслуживаться соответствующим кластеризованным индексом, но также может быть ограниченный некластеризованный индекс.

Вам также необходимо учитывать ширину индекса кластерного индекса, в частности, поскольку он влияет на все ваши некластеризованные индексы и влияние вставок на разбиения страниц.

Я рекомендую книгу SQL Server 2008 Query Performance Tuning Distilled, чтобы узнать больше о проблемах.

Ответ 2

Да. По умолчанию для всех первичных ключей создается уникальный кластеризованный индекс, но вместо него вы можете создать уникальный некластеризованный индекс.

Что касается подходящего выбора, я бы сказал, что для 80-90% создаваемых таблиц вы обычно хотите, чтобы кластерный индекс был основным ключом, но это не всегда так.

Вы обычно делаете кластеризованный индекс чем-то еще, если вы выполняете сканирование большого диапазона на этом "что-то еще". Например, если у вас есть синтетический первичный ключ *, но у вас есть столбец даты, который вы обычно запрашиваете с точки зрения диапазона, вам часто требуется, чтобы столбец даты был наиболее значимым столбцом в вашем кластерном индексе.

* Обычно это делается с помощью столбца INT IDENTITY, как PK в таблице.

Ответ 3

Да, по умолчанию он строит кластерный индекс первичного ключа.

Ответ 4

Чтобы быть прямым, SQL создает индекс для ключевого слова PRIMARY KEY (PK). Этот индекс является уникальным кластерным индексом.

sqlvogel поднимает важный момент в его работе. У вас может быть только один индекс "CLUSTERED". Если у вас уже есть один до объявления PK, тогда ваш ключ будет НЕОБХОДИМО. Это немного более подробно, чем ответ по умолчанию на этот вопрос. Следует также отметить, что PK не может иметь значения NULL.

Обратите внимание, что этот индекс может меняться в зависимости от предыдущих ограничений или индекса в таблице. Кроме того, вы можете объявить подробности этого индекса при создании в зависимости от того, как вы выписываете код:

< table_constraint > ::= [ CONSTRAINT constraint_name ] 
{ [ { PRIMARY KEY | UNIQUE } 
    [ CLUSTERED | NONCLUSTERED ] 
    { ( column [ ASC | DESC ] [ ,...n ] ) } 
    [ WITH FILLFACTOR = fillfactor ] 
    [ ON { filegroup | DEFAULT } ] 
] 

Пример:

CREATE TABLE MyTable
(
Id INT NOT NULL,
ForeignKeyId INT REFERENCES OtherTable(Id) NOT NULL,
Name VARCHAR(50) NOT NULL,
Comments VARCHAR(500) NULL,

PRIMARY KEY NONCLUSTERED (Id, ForeignKeyId)
)

Ответ 5

Нет, это не так, если в таблице уже есть индекс, указанный в таблице

Ответ 6

Я просто сталкиваюсь с тем же путаницей, Просто создал следующий script для тестирования:

create database mytest
go
use mytest
go
create table x
(
id int primary key
)
go
create table y 
(
    id int 
)
go
select * from sys.indexes where object_id = object_id(N'x') or object_id=object_Id(N'y')
go

Первая таблица x с первичным ключом получает кластеризованный индекс, а таблица y не получает никаких индексов, так как первичного ключа нет.

Подтвержден следующий пункт о кластеризованных индексах:

  • Когда мы создадим таблицу с Кластеризацией с Первичным ключом, будет создан по умолчанию

  • Когда мы создаем таблицу без первичного ключа, кластеризованный индекс не будет создан.

  • Будет существовать единый кластерный индекс, поскольку он зависит от ключа индекса Стоимость. Замыкание строк данных в таблице может быть только в одном на основе значения ключа индекса.