¿Cuáles son las consideraciones de rendimiento entre el uso de una PK amplia frente a una clave sintética y UQ separadas?

10

Tengo varias tablas donde los registros se pueden identificar de forma exclusiva con varios campos comerciales amplios. En el pasado, he usado estos campos como PK, con estos beneficios en mente:

  • Sencillez; no hay campos extraños y solo un índice
  • La agrupación en clúster permite combinaciones de fusión rápidas y filtros basados ​​en rango

Sin embargo, he escuchado un caso para crear una IDENTITY INTPK sintética y, en su lugar, aplicar la clave comercial con una UNIQUErestricción separada . La ventaja es que el PK estrecho genera índices secundarios mucho más pequeños.

Si una tabla no tiene índices distintos al PK, no veo ninguna razón para favorecer el segundo enfoque, aunque en una tabla grande probablemente sea mejor suponer que los índices pueden ser necesarios en el futuro y, por lo tanto, favorecen el PK sintético estrecho . ¿Me estoy perdiendo alguna consideración?

Por cierto, no estoy discutiendo contra el uso de claves sintéticas en almacenes de datos, solo estoy interesado en cuándo usar una PK amplia y única y cuándo usar una PK estrecha más un Reino Unido amplio.

Jon de todos los oficios
fuente
1
puede encontrar esto o esto útil entre otras preguntas en el sitio
Jack dice que intente topanswers.xyz el

Respuestas:

11

No existe una desventaja significativa al usar la clave natural como índice agrupado

  • no hay índices no agrupados
  • no hay claves externas que hagan referencia a esta tabla (es una fila principal)

La desventaja sería el aumento de las divisiones de página a medida que las inserciones de datos se distribuirían a través de los datos, en lugar de al final.

Cuando tiene índices FK o NC, el uso de un índice agrupado estrecho, numérico y creciente tiene ventajas. Solo repite unos pocos bytes de datos por entrada NC o FK, no la clave business / natural.

En cuanto a por qué, lea también los 5 artículos de Google

Tenga en cuenta que evité el uso de "clave primaria".

Puede tener el índice agrupado en la clave sustituta pero mantener el PK en las reglas de negocio pero como no agrupado. Solo asegúrese de que el clúster sea único porque SQL agregará un "uniquifier" para que sea así.

Finalmente, puede tener sentido tener una clave sustituta pero no a ciegas en cada tabla : muchas tablas no necesitan una, o donde una clave compuesta de las tablas primarias será suficiente

gbn
fuente
+1 para la referencia Sra. Tripp excelentes artículos en indexación.
Fabricio Araujo
2
+1 para el punto de que el rendimiento no tiene nada que ver con las claves principales y todo que ver con los índices.
nvogel
4

Aunque me arriesgo a decir lo obvio, un índice en una clave sustituta (un número de identificación) es útil si necesita ubicar las cosas por su número de identificación. Los usuarios no van a tratar con el número de identificación; van a tratar con texto legible por humanos. Por lo tanto, debe pasar mucho el texto y su número de identificación, de modo que la interfaz de usuario pueda mostrar el texto y operar con el número de identificación.

Los dbms usarán ese tipo de índice para admitir claves externas, si las define de esa manera.

A veces puede mejorar el rendimiento utilizando números de identificación como claves foráneas, pero no es una mejora absoluta. En nuestro sistema OLTP, las claves externas que usan claves naturales superaron a las claves externas que usan números de identificación en un conjunto de pruebas de aproximadamente 130 (creo) consultas representativas. (Debido a que la información importante a menudo se incluye en las claves, el uso de las claves naturales evitó muchas uniones.) La aceleración media fue un factor de 85 (las uniones que usaron números de identificación tardaron 85 veces más en devolver las filas).

Las pruebas mostraron que las uniones en números de identificación no funcionarían más rápido que las lecturas en claves naturales en nuestra base de datos hasta que ciertas tablas alcanzaran muchos millones de filas. El ancho de la fila tiene mucho que ver con eso: las filas más anchas significan que caben menos filas en una página, por lo que debe leer más páginas para obtener filas 'n'. Casi todas nuestras mesas están en 5NF; La mayoría de las mesas son bastante estrechas.

Para cuando las uniones comiencen a realizar lecturas simples aquí , colocar tablas e índices críticos en un disco de estado sólido podría nivelar el rendimiento en cientos de millones de filas.

Mike Sherrill 'Retiro del gato'
fuente
3

Tengo una base de datos oltp completa diseñada usando columnas de identidad para clustering + pk. Funciona bastante rápido en la inserción / búsqueda, pero he visto algunos problemas:
1. la opción de relleno de índice es inútil porque las inserciones ocurren solo al final del índice
2. más espacio de almacenamiento. Tengo tablas con decenas de millones de registros y 1 int ocupa espacio por sí mismo. Cada tabla con una columna de identidad para su paquete debe tener otro índice para las búsquedas comerciales, por lo que se requiere aún más almacenamiento.
3. escalabilidad. Este es el peor problema. Debido a que cada inserción va al final del índice, cada inserción enfatizará solo el final del índice (asignación, io para escrituras, etc.). Al utilizar una clave comercial como clave de agrupación, puede distribuir las inserciones de manera uniforme en el índice. Eso significa que acaba de eliminar una gran zona activa. Puede usar fácilmente más archivos para un índice, cada archivo en una unidad separada, cada unidad trabajando por separado.

Comencé a cambiar mis tablas de columnas de identidad a claves naturales (tal vez separadas para clustering y pk). Simplemente se siente mejor ahora.

Sugeriría lo siguiente (al menos para un oltp db):
1. use como clave de agrupamiento las columnas correctas en el orden correcto para optimizar las consultas más frecuentes
2. use un pk las columnas correctas que tengan sentido para su tabla

Si la clave agrupada no es simple y contiene caracteres (char [], varchar, nvarchar), creo que la respuesta es 'depende', debe analizar individualmente cada caso.

Mantengo el siguiente principio: optimizar para la consulta más común y minimizar el peor de los casos.

Casi olvido un ejemplo. Tengo algunas tablas que hacen referencia a sí mismas. Si esa tabla tiene una columna de identidad para su clave principal, entonces insertar una fila puede requerir una actualización, e insertar más de una fila a la vez puede ser difícil, si no imposible (depende del diseño de la tabla).

Catalin Adler
fuente
44
Su concepto de "punto de acceso" es un mito: dba.stackexchange.com/questions/1584/... Y cuando dice "Simplemente se siente mejor ahora". hiciste un punto de referencia?
gbn
44
Sí, las escrituras se realizan en la memoria, no directamente en el disco. Si escribe 20 filas nuevas en una página, solo hay una escritura física en el archivo de datos cuando ocurre el punto de control.
mrdenny
@mrdenny con suficientes inserciones escribiendo todo al final del índice enviaría todas las solicitudes de escritura io al mismo archivo. Sospecho que al usar transacciones oltp normales, este escenario será difícil de reproducir, pero usando algunos escenarios especiales como la inserción de registros masivos / por lotes, el uso de ssis para mover algunos datos comerciales lo llevará allí.
Catalin Adler
1
@ user973156 sí, todas las solicitudes le harían al mismo archivo, pero las escrituras en realidad no van al disco hasta el punto de control, que solo ocurre cada minuto (de forma predeterminada) o cuando el búfer de escritura está lleno al 50%. No importa cómo escriba los datos, esta regla todavía se aplica.
mrdenny
2
@ user973156 El uso de una clave de agrupación distribuida aleatoriamente causará la fragmentación del índice. La fragmentación del índice causará problemas de rendimiento. Y su tabla será lo suficientemente grande como para llevar a cabo la desfragmentación del índice "mucho tiempo", y ocupará espacio de registro y potencialmente espacio de tempDB. Cuando gente como Kimberly Tripp me dice que es una buena idea, escucho. ( sqlskills.com/BLOGS/KIMBERLY/post/… )
Matt M
2

Desde el punto de vista del rendimiento, la elección de qué tecla es la clave "primaria" no hace ninguna diferencia. No hay diferencia entre usar una CLAVE PRIMARIA y una restricción ÚNICA para aplicar sus claves.

El rendimiento está determinado por la selección y el tipo de índices y otras opciones de almacenamiento y por la forma en que se utilizan las claves en las consultas y el código.

nvogel
fuente