Кластеризованный индекс во временной таблице

#sql #sql-server #tsql #temp-tables #clustered-index

#sql #sql-сервер #tsql #временные таблицы #кластеризованный индекс

Вопрос:

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

 CREATE TABLE #t1 (c1 int, c2 varchar(20), c3(varchar(50)...)

CREATE CLUSTERED INDEX ix_t1 ON #t1(c3) ON [PRIMARY]
  

Я хотел улучшить это, переместив КЛАСТЕРИЗОВАННЫЙ индекс в объявление таблицы (более удобное для кэширования), но c3 не уникален, поэтому это не работает:

 CREATE TABLE #t1 (c1 int, c2 varchar(20), c3 varchar(50)..., UNIQUE CLUSTERED (c3))
  

Есть ли способ объявить кластеризованный, который не является уникальным в объявлении временной таблицы?

Ответ №1:

Да, это возможно в SQL Server 2014 и выше, создать таблицу в MSDN. С 2014 года вы можете указывать индексы, встроенные в инструкцию create table .

  if object_id('tempdb..#t1') is not null drop table #t1;

CREATE TABLE #t1 (
    c1 int, 
    c2 varchar(20), 
    c3 varchar(50), 

    index [CIX_c3] CLUSTERED (c3),
    index [IX_c1] nonclustered (c1)
)

insert #t1(c3) values ('a'), ('a'), ('a')

select * from #t1
  

Ответ №2:

Нет, нет … наличие возможности определять кластеризацию в качестве опции при создании таблицы заключается в поддержке объявления ограничений первичного ключа и уникальных столбцов, которые сами создают индексы. Другими словами, CLUSTERED в CREATE TABLE инструкции указывается, должен ли индекс, созданный UNIQUE ограничением, быть кластеризованным или некластеризованным, что важно, поскольку таблица может иметь только один кластеризованный индекс.

Комментарии:

1. Спасибо. Решена проблема путем добавления столбца в индекс, чтобы сделать его уникальным.

Ответ №3:

Это можно сделать, добавив identity столбец, например:

 CREATE TABLE #t1 (rowID int not null identity(1,1),
                     c1 int, c2 varchar(20), c3 varchar(50),
                     UNIQUE CLUSTERED (c3,rowID)
                 )
  

Включение rowID в индекс гарантирует, что он уникален, даже если c3 это не так.

Вы проверяете индекс, созданный с помощью:

 EXEC tempdb.dbo.sp_helpindex '#t1'