Индекс по умолчанию для первичного ключа - PullRequest
15 голосов
/ 20 июля 2010

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

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

Спасибо.

Ответы [ 6 ]

16 голосов
/ 20 июля 2010

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

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 , чтобы узнать больше о проблемах.

11 голосов
/ 20 июля 2010

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

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

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

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

2 голосов
/ 09 апреля 2012

Чтобы быть прямым, 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)
)
2 голосов
/ 20 июля 2010

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

1 голос
/ 09 августа 2017

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

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 не получает индексы, так как нет первичного ключа.

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

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

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

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

1 голос
/ 31 октября 2012

Нет, это не так, если в таблице уже определен индекс

...