Pregunta

Tengo varias tablas cuyos únicos datos únicos son una columna de identificador único (un Guid).Debido a que los guids no son secuenciales (y se generan en el lado del cliente, por lo que no puedo usar newequentialid()), he creado un índice no primario y no agrupado en este campo de ID en lugar de darle a las tablas un índice primario agrupado. llave.

Me pregunto cuáles son las implicaciones de rendimiento para este enfoque.He visto a algunas personas sugerir que las tablas deberían tener un int de incremento automático ("identidad") como clave primaria agrupada incluso si no tiene ningún significado, ya que significa que el motor de la base de datos puede usar ese valor para rápidamente busque una fila en lugar de tener que usar un marcador.

Mi base de datos está replicada mediante fusión en varios servidores, por lo que he evitado las columnas de identidad int porque son un poco difíciles de realizar en la replicación.

¿Cuáles son tus pensamientos?¿Deberían las tablas tener claves primarias?¿O está bien no tener índices agrupados si no hay columnas sensatas para indexar de esa manera?

¿Fue útil?

Solución

Cuando se trata de índices, debe determinar para qué se utilizará su tabla.Si principalmente inserta 1000 filas por segundo y no realiza ninguna consulta, entonces un índice agrupado afecta el rendimiento.Si realiza 1000 consultas por segundo, no tener un índice provocará un rendimiento muy malo.Lo mejor que puede hacer al intentar ajustar consultas/índices es utilizar el Analizador de planes de consultas y el Analizador de perfiles SQL en SQL Server.Esto le mostrará dónde se encuentra con costosos escaneos de tablas u otros bloqueadores de rendimiento.

En cuanto al argumento GUID vs ID, puede encontrar personas en línea que confían en ambos.Siempre me han enseñado a usar GUID a menos que tenga una muy buena razón para no hacerlo.Jeff tiene una buena publicación que habla sobre las razones para usar GUID: https://blog.codinghorror.com/primary-keys-ids-versus-guids/.

Como ocurre con casi todo lo relacionado con el desarrollo, si busca mejorar el rendimiento, no existe una única respuesta correcta.Realmente depende de lo que intente lograr y de cómo implemente la solución.La única respuesta verdadera es probar, probar y probar nuevamente con métricas de desempeño para asegurarse de que está cumpliendo sus objetivos.

Editar] @matt, después de investigar más sobre el debate GUID/ID, me encontré con esta publicación.Como mencioné antes, no existe una verdadera respuesta correcta o incorrecta.Depende de sus necesidades de implementación específicas.Pero estas son algunas razones bastante válidas para usar GUID como clave principal:

Por ejemplo, existe un problema conocido como "punto caliente", donde ciertas páginas de datos en una tabla están bajo una contención de divisas relativamente alta.Básicamente, lo que sucede es que la mayor parte del tráfico en una tabla (y por lo tanto los bloqueos a nivel de página) ocurre en un área pequeña de la tabla, hacia el final.Los registros nuevos siempre irán a este punto de acceso porque IDENTITY es un generador de números secuenciales.Estas inserciones son problemáticas porque requieren un bloqueo de página exclusivo en la página a la que se agregan (el punto de acceso).Esto serializa efectivamente todas las inserciones en una tabla gracias al mecanismo de bloqueo de página.NewID(), por otro lado, no sufre puntos de acceso.Los valores generados usando la función NewID() solo son secuenciales para ráfagas cortas de inserciones (donde la función se llama muy rápidamente, como durante una inserción de varias filas), lo que hace que las filas insertadas se distribuyan aleatoriamente por las páginas de datos de la tabla. de todo al final, eliminando así un punto de acceso de las inserciones.

Además, debido a que las inserciones se distribuyen aleatoriamente, la posibilidad de divisiones de página se reduce considerablemente.Si bien una página dividida aquí y allá no es tan mala, los efectos se acumulan rápidamente.Con IDENTITY, el factor de relleno de la página es bastante inútil como mecanismo de ajuste y también podría establecerse en 100%: las filas nunca se insertarán en ninguna página excepto en la última.Con NewID(), puedes utilizar Fill Factor como una herramienta que permite el rendimiento.Puede establecer el factor de llenado en un nivel que se aproxime al crecimiento del volumen estimado entre reconstrucciones del índice y luego programar las reconstrucciones durante las horas de menor actividad usando dbcc reindex.Esto efectivamente retrasa los impactos en el rendimiento de las divisiones de páginas hasta las horas de menor actividad.

Si incluso pensar es posible que necesite habilitar la replicación para la tabla en cuestión; entonces también podría convertir la PK en un identificador único y marcar el campo guid como ROWGUIDCOL.La replicación requerirá un campo guid con un valor único con este atributo y agregará uno si no existe ninguno.Si existe un campo adecuado, simplemente utilizará el que está allí.

Otro gran beneficio más de usar GUID para PK es el hecho de que, de hecho, se garantiza que el valor es único, no solo entre todos los valores generados por este servidor, pero todos los valores generados por todo computadoras, ya sea su servidor de base de datos, servidor web, servidor de aplicaciones o máquina cliente.Prácticamente todos los lenguajes modernos tienen la capacidad de generar un guid válido ahora; en .NET puedes usar System.Guid.NewGuid.Esto es MUY útil cuando se trata de conjuntos de datos maestros-detalles almacenados en caché en particular.No es necesario emplear locos esquemas de claves temporales sólo para relacionar los registros antes de confirmarlos.Simplemente obtiene un nuevo Guid perfectamente válido del sistema operativo para el valor de clave permanente de cada nuevo registro en el momento en que se crea el registro.

http://forums.asp.net/t/264350.aspx

Otros consejos

La clave principal tiene tres propósitos:

  • indica que las columnas deben ser únicas
  • indica que las columnas no deben ser nulas
  • documentar la intención de que este sea el identificador único de la fila

Los dos primeros se pueden especificar de muchas maneras, como ya lo ha hecho.

La tercera razón es buena:

  • para humanos, para que puedan ver fácilmente tu intención
  • para la computadora, por lo que un programa que pueda comparar o procesar su tabla puede consultar la base de datos para obtener la clave principal de la tabla.

Una clave principal no tiene que ser un campo numérico que se incrementa automáticamente, por lo que diría que es una buena idea especificar su columna guid como clave principal.

Simplemente intervengo, porque Matt me ha provocado un poco.

Debe comprender que, aunque un índice agrupado se coloca en la clave principal de una tabla de forma predeterminada, los dos conceptos están separados y deben considerarse por separado.Un CIX indica la forma en que los NCIX almacenan y hacen referencia a los datos, mientras que el PK proporciona una unicidad para cada fila para satisfacer los requisitos LÓGICOS de una tabla.

Una mesa sin CIX es solo un montón.Una tabla sin PK a menudo se considera "no una tabla".Es mejor comprender los conceptos de PK y CIX por separado para poder tomar decisiones sensatas en el diseño de bases de datos.

Robar

Nadie respondió la pregunta real:¿Cuáles son las ventajas y desventajas de una tabla SIN PK NI un índice AGRUPADO?En mi opinión, si optimiza para inserciones más rápidas (especialmente inserciones masivas incrementales, p. ej.cuando carga datos de forma masiva en una tabla que no está vacía), dicha tabla:SIN índice agrupado, SIN restricciones, SIN claves externas, SIN valores predeterminados y SIN clave primaria, en una base de datos con modelo de recuperación simple, es lo mejor.Ahora, si alguna vez desea consultar esta tabla (en lugar de escanearla en su totalidad), es posible que desee agregar índices no agrupados y no únicos según sea necesario, pero mantenerlos al mínimo.

Yo también siempre he escuchado que tener un int de incremento automático es bueno para el rendimiento, incluso si en realidad no lo usas.

Una clave principal no tiene por qué ser un campo de incremento automático; en muchos casos, esto solo significa que está complicando la estructura de su tabla.

En cambio, una clave primaria debe ser la colección mínima de atributos (tenga en cuenta que la mayoría de los DBMS permitirán una clave primaria compuesta) que identifique de forma única una tupla.

En términos técnicos, debería ser el campo del que todos los demás campos de la tupla dependen completamente funcionalmente.(Si no es así, es posible que deba normalizar).

En la práctica, los problemas de rendimiento pueden significar que se fusionan tablas y se utiliza un campo incremental, pero creo recordar algo acerca de que la optimización prematura es mala...

Dado que está realizando una replicación, sus identidades correctas son algo que debe evitar.Haría que su GUID fuera una clave principal pero no agrupada, ya que no puede usar newequentialid.Eso me parece tu mejor curso.Si no lo convierte en un PK pero le pone un índice único, tarde o temprano eso puede causar que las personas que mantienen el sistema no comprendan las relaciones FK adecuadamente, introduciendo errores.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top