Crear un índice en una variable de tabla

Resuelto GordyII asked hace 15 años • 3 respuestas

¿Se puede crear un índice en una variable de tabla en SQL Server 2000?

es decir

DECLARE @TEMPTABLE TABLE (
     [ID] [int] NOT NULL PRIMARY KEY
    ,[Name] [nvarchar] (255) COLLATE DATABASE_DEFAULT NULL 
)

¿Puedo crear un índice en Name?

GordyII avatar May 20 '09 10:05 GordyII
Aceptado

La pregunta está etiquetada como SQL Server 2000, pero para beneficio de las personas que desarrollan la última versión, la abordaré primero.

Servidor SQL 2014

Además de los métodos para agregar índices basados ​​en restricciones que se analizan a continuación, SQL Server 2014 también permite especificar índices no únicos directamente con sintaxis en línea en declaraciones de variables de tabla.

La sintaxis de ejemplo para eso se encuentra a continuación.

/*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*/
);

Actualmente, los índices filtrados y los índices con columnas incluidas no se pueden declarar con esta sintaxis; sin embargo, SQL Server 2016 lo relaja un poco más. Desde CTP 3.1 ahora es posible declarar índices filtrados para variables de tabla. Según RTM, puede darse el caso de que las columnas incluidas también estén permitidas, pero la posición actual es que "probablemente no lleguen a SQL16 debido a limitaciones 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*/
)

Servidor SQL 2000 - 2012

¿Puedo crear un índice en Nombre?

Respuesta corta: sí.

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

Una respuesta más detallada se encuentra a continuación.

Las tablas tradicionales en SQL Server pueden tener un índice agrupado o estar estructuradas como montones .

Los índices agrupados se pueden declarar como únicos para no permitir valores de clave duplicados o por defecto como no únicos. Si no es único, SQL Server agrega silenciosamente un unificador a cualquier clave duplicada para hacerla única.

Los índices no agrupados también se pueden declarar explícitamente como únicos. De lo contrario, para el caso no único, SQL Server agrega el localizador de filas (clave de índice agrupada o RID para un montón) a todas las claves de índice (no solo duplicadas), esto nuevamente garantiza que sean únicas.

En SQL Server 2000 - 2012, los índices de las variables de la tabla solo se pueden crear implícitamente mediante la creación de una restricción UNIQUEo PRIMARY KEY. La diferencia entre estos tipos de restricciones es que la clave principal debe estar en columnas que no aceptan valores NULL. Las columnas que participan en una restricción única pueden ser anulables. (aunque la implementación de restricciones únicas de SQL Server en presencia de NULLs no se ajusta a lo especificado en el Estándar SQL). Además, una tabla solo puede tener una clave principal pero múltiples restricciones únicas.

Ambas restricciones lógicas se implementan físicamente con un índice único. Si no se especifica explícitamente lo contrario, se PRIMARY KEYconvertirá en el índice agrupado y las restricciones únicas no agrupadas, pero este comportamiento se puede anular especificando CLUSTEREDo NONCLUSTEREDexplícitamente con la declaración de restricción (sintaxis de ejemplo).

DECLARE @T TABLE
(
A INT NULL UNIQUE CLUSTERED,
B INT NOT NULL PRIMARY KEY NONCLUSTERED
)

Como resultado de lo anterior, los siguientes índices se pueden crear implícitamente en variables de tabla en 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                                 |
+-------------------------------------+-------------------------------------+

El último requiere un poco de explicación. En la definición de variable de tabla al comienzo de esta respuesta, el índice no únicoName y no agrupado se simula mediante un índice únicoName,Id (recuerde que SQL Server agregaría silenciosamente la clave de índice agrupado a la clave NCI no única de todos modos).

También se puede lograr un índice agrupado no único agregando manualmente una IDENTITYcolumna para que actúe como unificador.

DECLARE @T TABLE
(
A INT NULL,
B INT NULL,
C INT NULL,
Uniqueifier INT NOT NULL IDENTITY(1,1),
UNIQUE CLUSTERED (A,Uniqueifier)
)

Pero esta no es una simulación precisa de cómo normalmente se implementaría un índice agrupado no único en SQL Server, ya que esto agrega el "Uniqueificador" a todas las filas. No sólo aquellos que lo requieren.

Martin Smith avatar Jun 29 '2013 21:06 Martin Smith