Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Criando um índice em uma variável de tabela


A pergunta está marcada como SQL Server 2000, mas para o benefício das pessoas que estão desenvolvendo na versão mais recente, abordarei isso primeiro.

SQL Server 2014

Além dos métodos de adição de índices baseados em restrições discutidos abaixo, o SQL Server 2014 também permite que índices não exclusivos sejam especificados diretamente com sintaxe embutida em declarações de variáveis ​​de tabela.

Sintaxe de exemplo para isso está abaixo.
/*SQL Server 2014+ compatible inline index syntax*/
DECLARE @T TABLE (
C1 INT INDEX IX1 CLUSTERED, /*Single column indexes can be declared next to the column*/
C2 INT INDEX IX2 NONCLUSTERED,
       INDEX IX3 NONCLUSTERED(C1,C2) /*Example composite index*/
);

Índices filtrados e índices com colunas incluídas não podem ser declarados atualmente com esta sintaxe, no entanto, SQL Server 2016 relaxa isso um pouco mais. A partir do CTP 3.1 agora é possível declarar índices filtrados para variáveis ​​de tabela. Por RTM, pode ser o caso de colunas incluídas também serem permitidas, mas a posição atual é que elas "provavelmente não chegarão ao SQL16 devido a restrições de recursos"
/*SQL Server 2016 allows filtered indexes*/
DECLARE @T TABLE
(
c1 INT NULL INDEX ix UNIQUE WHERE c1 IS NOT NULL /*Unique ignoring nulls*/
)

SQL Server 2000 - 2012

Posso criar um índice em Nome?

Resposta curta:Sim.
DECLARE @TEMPTABLE TABLE (
  [ID]   [INT] NOT NULL PRIMARY KEY,
  [Name] [NVARCHAR] (255) COLLATE DATABASE_DEFAULT NULL,
  UNIQUE NONCLUSTERED ([Name], [ID]) 
  ) 

Uma resposta mais detalhada está abaixo.

As tabelas tradicionais no SQL Server podem ter um índice clusterizado ou serem estruturadas como heaps.

Índices clusterizados podem ser declarados como exclusivos para não permitir valores de chave duplicados ou padrão como não exclusivos. Se não for exclusivo, o SQL Server adicionará silenciosamente um exclusivo a quaisquer chaves duplicadas para torná-las exclusivas.

Índices não clusterizados também podem ser declarados explicitamente como exclusivos. Caso contrário, para o caso não exclusivo, o SQL Server adiciona o localizador de linha (chave de índice clusterizado ou RID para um heap) a todas as chaves de índice (não apenas duplicatas), isso novamente garante que elas sejam exclusivas.

No SQL Server 2000 - 2012, índices em variáveis ​​de tabela só podem ser criados implicitamente criando um UNIQUE ou PRIMARY KEY limitação. A diferença entre esses tipos de restrição é que a chave primária deve estar em colunas não anuláveis. As colunas que participam de uma restrição exclusiva podem ser anuláveis. (embora a implementação de restrições exclusivas do SQL Server na presença de NULL s não está de acordo com o especificado no padrão SQL). Além disso, uma tabela pode ter apenas uma chave primária, mas várias restrições exclusivas.

Ambas as restrições lógicas são implementadas fisicamente com um índice exclusivo. Se não for especificado de outra forma, a PRIMARY KEY se tornará o índice clusterizado e as restrições exclusivas não clusterizadas, mas esse comportamento pode ser substituído especificando CLUSTERED ou NONCLUSTERED explicitamente com a declaração de restrição (sintaxe de exemplo)
DECLARE @T TABLE
(
A INT NULL UNIQUE CLUSTERED,
B INT NOT NULL PRIMARY KEY NONCLUSTERED
)

Como resultado do acima, os seguintes índices podem ser criados implicitamente em variáveis ​​de tabela no SQL Server 2000 - 2012.
+-------------------------------------+-------------------------------------+
|             Index Type              | Can be created on a table variable? |
+-------------------------------------+-------------------------------------+
| Unique Clustered Index              | Yes                                 |
| Nonunique Clustered Index           |                                     |
| Unique NCI on a heap                | Yes                                 |
| Non Unique NCI on a heap            |                                     |
| Unique NCI on a clustered index     | Yes                                 |
| Non Unique NCI on a clustered index | Yes                                 |
+-------------------------------------+-------------------------------------+

O último requer um pouco de explicação. Na definição da variável da tabela no início desta resposta, o não exclusivo índice não clusterizado em Name é simulado por um único indexar em Name,Id (lembre-se de que o SQL Server adicionaria silenciosamente a chave de índice clusterizado à chave NCI não exclusiva de qualquer maneira).

Um índice clusterizado não exclusivo também pode ser obtido adicionando manualmente um IDENTITY coluna para atuar como um exclusivo.
DECLARE @T TABLE
(
A INT NULL,
B INT NULL,
C INT NULL,
Uniqueifier INT NOT NULL IDENTITY(1,1),
UNIQUE CLUSTERED (A,Uniqueifier)
)

Mas esta não é uma simulação precisa de como um índice clusterizado não exclusivo normalmente seria implementado no SQL Server, pois isso adiciona o "Uniqueifier" a todas as linhas. Não apenas aqueles que exigem isso.