¿Por qué las Vistas indexadas no permiten índices agrupados no únicos?

12

He estado buscando el uso de Vistas indexadas para aumentar el rendimiento en algunas de nuestras vistas más utilizadas.

Sin embargo, las vistas indexadas no admiten índices agrupados no únicos, lo que va un poco en contra de la precedencia establecida por el resto de la estructura de la base de datos.

Por ejemplo, aquí hay una versión simplificada de un par de nuestras tablas.

-Groups-
Group ID    GroupName

-Users-
UserKey    UserName    FullName     GroupID

Los índices están en Groups.GroupID (no agrupado) y Users.GroupID (agrupado). La clave agrupada se encuentra en GroupID en la tabla Usuarios, ya que normalmente se recuperaría un rango de usuarios de un grupo específico. Obviamente, tendría varios usuarios por grupo, por lo que este índice agrupado no es único.

Esto me deja un poco inseguro de cómo seguir esta precedencia al indexar mis vistas, como este ejemplo, ya que no puedo tener un índice agrupado no único.

ConsumableID    ConsumableVariantID AllowThresholdOverwrite FullPath    GroupID ManufacturerID  Type    ModelID
101              29                 1                       0.1.2.4.    4       3               3       2

En realidad, el único valor en esta Vista que siempre sería único es la columna ConsumableID, por lo que no tengo muchas opciones sobre dónde colocar mi índice.

¿Por qué las vistas no permiten índices agrupados no únicos cuando las tablas normales lo hacen?

Amistoso
fuente
3
Hay una breve explicación cerca de la parte inferior de esta página titulada '¿Por qué el primer índice de una vista tiene que estar CLUSIFICADO y ÚNICO?' Pero no hace muchos detalles. Definitivamente me interesaría escuchar una explicación más detallada.
Steve Pettifer
55
Un par de comentarios: 1 - No hay ninguna razón por la que no pueda agruparse (GroupID, UserID). No se limite a una sola columna para la clave. 2 - Me imagino que la limitación para una vista es porque este es un objeto de datos suplementario que necesita tener filas fácilmente vinculadas a los índices NC. Para una tabla, la clave CI no única recibe un int, pero creo que eso sería más desafiante con una vista indexada, ya que no es una tabla real pero necesita REFLEJAR una tabla real.
JNK

Respuestas:

22

La siguiente explicación se proporciona en este artículo técnico de Microsoft :

¿Por qué el primer índice de una vista tiene que estar CLUSIFICADO y ÚNICO?

Debe ser ÚNICO para permitir la búsqueda fácil de registros en la vista por valor clave durante el mantenimiento de la vista indexada, y para evitar la creación de vistas con duplicados, lo que requeriría una lógica especial para mantener. Debe estar agrupado porque solo un índice agrupado puede imponer unicidad y almacenar las filas al mismo tiempo.

SQL Server utiliza un sistema de álgebra delta para mantener las vistas indexadas en sintonía con los datos base. También incorpora automáticamente operadores de plan de consulta de mantenimiento de vistas para cada consulta DML que afecta a una o más vistas indexadas. Tener un índice agrupado único en la vista simplifica enormemente los detalles de implementación.

La disposición actual permite incorporar formas de árbol de operador de mantenimiento de forma fija en el árbol de consulta DML base, proporcionando ortogonalidad que también simplifica las pruebas. En última instancia, las vistas indexadas podrían mejorarse un día para admitir índices agrupados no únicos, pero, de nuevo, todo es posible con un tiempo ilimitado y recursos ilimitados (ninguno de los cuales se aplica al equipo de desarrollo de SQL Server en el momento de la escritura).

Para ver un ejemplo que muestra cómo se puede obtener la compleja construcción del plan de consulta de actualización y con qué facilidad pueden aparecer errores sutiles, vea este ejemplo de un error que ocurre con los MERGEíndices filtrados (una característica que tiene una conexión cercana con las vistas indexadas).

Paul White 9
fuente
2
Puede ocurrir un error similar si intenta actualizar una vista indizada que tiene una GROUP BYcláusula pero no todas las expresiones de agrupación son claves en el índice agrupado. Es válido a partir de SQL Server 2014.
Quassnoi
4

En SQL Server, todas las claves de índice deben ser internamente únicas. Esto es necesario para obtener claves de bloqueo que aborden exactamente una fila. También es necesario para el mantenimiento del índice. Imagine un NCI en una columna que solo tiene un valor (100% duplicados). Si se elimina una fila de la tabla, el motor de almacenamiento debe encontrar la fila NCI correspondiente y eliminarla también. Si todas las filas del NCI no se pueden distinguir, esto sería imposible.

Entonces verá que el CI en una vista debe ser (internamente) único para que el motor funcione.

Si no crea un índice único, SQL Server lo hace único internamente. En el caso de un NCI en una tabla de montón, agrega el marcador de fila. En el caso de un CI no único, agrega una columna de uniquifier. En el caso de un NCI en una tabla con un elemento de configuración, agrega cualquier columna de clave de elemento de configuración que usted mismo no haya especificado (esto puede incluir el uniquifier).

No hay una columna obvia que pueda agregarse en caso de una vista indizada. Por lo tanto, SQL Server no puede hacer esto automáticamente.

Normalmente, es bastante obvio para un humano qué columnas puede agregar para que la vista tenga un conjunto único de columnas para usar en el elemento de configuración. Estas son normalmente las columnas PK o CI de una de las tablas subyacentes. Si la vista tiene un GROUP BYíndice normalmente en las teclas de agrupación.

usr
fuente
2
Sugiero revisar la redacción de esta respuesta. Si bien contiene un punto válido con respecto a la pregunta original, puede parecer que sugiere que todos los índices no únicos contienen uniquificantes, lo cual no es el caso.
spaghettidba
@spaghettidba gracias, no me di cuenta de eso. Espero que sea mejor ahora.
usr
Lo siento aún no. Estás mezclando dos cosas juntas. Los índices no agrupados no tienen que ser únicos y no están sin clasificar internamente: no está aclarando este punto lo suficiente. Todo lo que diga en su respuesta se aplica solo a los índices agrupados.
spaghettidba
@spaghettidba Los NCI siempre son únicos internamente. Siempre pueden generar todas las claves de CI como parte de un plan de consulta. Consulte pastebin.com/vkGHpCsR La página de datos del NCI contiene ambas columnas.
usr
Ya veo de dónde vienes. Varias hojas pueden compartir la misma clave de índice, pero la clave de agrupación siempre se incluye en los NCI. ¿Es suficiente decir que siempre son únicos internamente? No lo creo.
spaghettidba