Можно ли создать таблицу без кластеризованного индекса
Что проверяют
Знаете ли вы, что таблица без кластеризованного индекса в SQL Server называется кучей, и понимаете ли, чем за это платите на чтении. Заодно смотрят, различаете ли вы первичный ключ и способ хранения.
Как отвечать
Да, такая таблица называется heap: строки лежат в произвольном порядке, а ссылкой на строку служит физический адрес RID. Важная оговорка: просто «не указать индекс» мало. Первичный ключ в SQL Server по умолчанию создаётся кластеризованным, поэтому кучу надо запросить явно:
create table dbo.Staging (
Id int not null,
Name nvarchar(100) not null,
constraint PK_Staging primary key nonclustered (Id)
);Когда куча уместна: промежуточные таблицы под массовую загрузку, журналы, куда в основном пишут, короткоживущие таблицы этапа обработки.
Чем платите: поиск по некластеризованному индексу требует дополнительного обращения к строке по RID, а обновление, увеличивающее строку в размере, оставляет на старом месте указатель на новое, и такие переадресации накапливаются. Лечится перестроением таблицы.
В EF Core кластер задаётся явно: ключ по умолчанию кластеризованный, а IsClustered(false) оставляет кучу, и кластер можно повесить на другой индекс.
Где спотыкаются
Уверены, что первичный ключ и кластеризованный индекс это одно и то же. Вещи разные: ключ это ограничение целостности, кластер это порядок хранения, совпадают они лишь по умолчанию и разводятся словом nonclustered.
Путают кучу с таблицей вообще без индексов. У кучи бывают некластеризованные, уникальные и отфильтрованные индексы, нет только кластеризованного.
Считают кучу выигрышем, потому что вставка быстрее. Выигрыш съедается на чтении: сканирование кучи читает и пустоты, оставшиеся после удалений, а каждый поиск по индексу добавляет обращение к строке.