Consultar llaves primarias, restricciones únicas e índices

Señal o problema observado

Necesitamos entender cómo se identifica cada fila y qué estructuras existen para conservar unicidad o apoyar búsquedas. Ver solo el nombre de un índice no basta: también importan el orden de sus columnas, las columnas incluidas y sus filtros.

Qué necesitamos distinguir

Una llave primaria identifica cada fila de forma única y una restricción UNIQUE impide repetir una combinación de valores. Un índice organiza valores para facilitar el acceso a las filas; puede apoyar una restricción sin ser por sí mismo una regla del modelo.

Una llave primaria y una restricción única se respaldan con índices únicos, pero no todo índice único es una restricción. Además, un índice normal puede ordenar columnas clave e incluir otras únicamente para cubrir una consulta.

Consulta

DECLARE @Tabla NVARCHAR(517) = N'dbo.Producto';
DECLARE @IdTabla INT = OBJECT_ID(@Tabla, N'U');

IF @IdTabla IS NULL
    THROW 50000, 'La tabla no existe o no es visible en esta base.', 1;

SELECT
    i.name AS Indice,
    CASE
        WHEN kc.type = N'PK' THEN N'LLAVE PRIMARIA'
        WHEN kc.type = N'UQ' THEN N'RESTRICCION UNICA'
        WHEN i.is_unique = 1 THEN N'INDICE UNICO'
        ELSE N'INDICE'
    END AS Clasificacion,
    i.type_desc AS TipoIndice,
    i.is_unique AS EsUnico,
    i.has_filter AS TieneFiltro,
    i.filter_definition AS Filtro,
    c.name AS Columna,
    ic.key_ordinal AS OrdenLlave,
    ic.is_descending_key AS EsDescendente,
    ic.is_included_column AS EsIncluida,
    i.is_disabled AS EstaDeshabilitado
FROM sys.indexes AS i
INNER JOIN sys.index_columns AS ic
    ON ic.object_id = i.object_id
   AND ic.index_id = i.index_id
INNER JOIN sys.columns AS c
    ON c.object_id = ic.object_id
   AND c.column_id = ic.column_id
LEFT JOIN sys.key_constraints AS kc
    ON kc.parent_object_id = i.object_id
   AND kc.unique_index_id = i.index_id
WHERE i.object_id = @IdTabla
  AND i.index_id > 0
  AND i.is_hypothetical = 0
ORDER BY
    i.index_id,
    ic.is_included_column,
    ic.key_ordinal,
    ic.index_column_id;

Parámetros o permisos

Un heap es una tabla sin índice clustered. Un índice hipotético conserva una definición para estimación, pero no una estructura utilizable; un índice materializado sí ocupa almacenamiento y puede responder consultas.

Cambia @Tabla por un nombre de dos partes. La cuenta necesita visibilidad sobre la tabla. La consulta omite el heap (index_id = 0) y los índices hipotéticos; se concentra en índices materializados con columnas registradas.

Cómo leer el resultado

El nivel hoja es la parte final del índice donde se encuentran sus filas o referencias. Una columna incluida se guarda allí sin participar en el orden de búsqueda.

Cada índice ocupa una o más filas. Las columnas clave tienen OrdenLlave mayor que cero. Su posición importa: un índice sobre (IdCliente, FechaPedido) no ofrece exactamente las mismas posibilidades que otro sobre (FechaPedido, IdCliente).

EsIncluida = 1 identifica una columna que no participa en el orden de la llave, pero se almacena en el nivel hoja para cubrir determinadas consultas. En esas filas OrdenLlave aparece como cero.

EsUnico = 1 impide duplicados en la llave del índice, sujeto al comportamiento de NULL y, si existe, al Filtro. La columna Clasificacion separa esa propiedad de una llave primaria o restricción única declarada.

Un índice filtrado solo contiene filas que cumplen Filtro. Un índice deshabilitado conserva su definición, pero no está disponible para mantener o responder consultas hasta reconstruirlo.

Qué conclusión sí permite obtener

Permite describir llaves e índices visibles de la tabla, su clasificación, orden, dirección, columnas incluidas, unicidad, filtro y estado. También permite comprobar si una restricción declarada está respaldada por el índice esperado.

Qué conclusión todavía no permite obtener

La fragmentación describe qué tan disperso está el orden físico de las páginas. Un plan de ejecución describe la estrategia elegida por SQL Server para una consulta.

La existencia de un índice no demuestra que una consulta lo use, que su orden sea adecuado ni que su costo de mantenimiento esté justificado. La ausencia de una llave primaria tampoco significa necesariamente que no exista otra regla de unicidad empresarial.

Esta consulta no mide lecturas, escrituras, fragmentación ni planes de ejecución. Tampoco recomienda crear o eliminar índices por sí sola.

Siguiente comprobación razonable

Relaciona cada índice con las consultas que realmente se ejecutan. Después revisa planes, estadísticas de uso y volumen de modificaciones antes de proponer cambios. Si falta una regla de integridad, valida primero los datos existentes y el comportamiento esperado del sistema.

Índice del recorrido

Desarrollo y exploración

22 artículos de Desarrollo y exploración
  1. 01Buscar una tabla o vista por nombre
  2. 02Buscar una columna en toda la base
  3. 03Buscar texto dentro de procedimientos, vistas y funciones
  4. 04Consultar dependencias de un objeto
  5. 05Listar relaciones y llaves foráneas
  6. 06Consultar llaves primarias, restricciones únicas e índices
  7. 07Listar columnas con tipo, longitud, nulabilidad y valor predeterminado
  8. 08Encontrar triggers y sus tablas asociadas
  9. 09Encontrar objetos modificados recientemente
  10. 10Obtener conteos aproximados de todas las tablas
  11. 11Medir el espacio utilizado por cada tabla
  12. 12Revisar columnas IDENTITY y su valor actual
  13. 13Detectar registros duplicados por una clave de negocio
  14. 14Detectar registros huérfanos
  15. 15Comparar dos conjuntos de datos
  16. 16Validar conversiones antes de modificar una columna
  17. 17Ejecutar un UPDATE con validación y reversión controlada
  18. 18Ejecutar un DELETE con respaldo lógico y reversión controlada
  19. 19Comparar la estructura de dos bases de datos
  20. 20Describir el resultado de una consulta o procedimiento
  21. 21Encontrar tablas sin llave primaria
  22. 22Buscar un valor en columnas seleccionadas