Tengo una aplicación que usa GUID como clave principal en casi todas las tablas y he leído que hay problemas de rendimiento al usar GUID como clave primaria. Honestamente, no he visto ningún problema, pero estoy a punto de comenzar una nueva aplicación y todavía quiero usar los GUID como las Claves primarias, pero estaba pensando en usar una Clave primaria compuesta (El GUID y quizás otro campo .)
Estoy usando un GUID porque son agradables y fáciles de administrar cuando tienes diferentes entornos como bases de datos de "producción", "prueba" y "dev", y también para la migración de datos entre bases de datos.
Usaré Entity Framework 4.3 y quiero asignar el Guid en el código de la aplicación, antes de insertarlo en la base de datos. (es decir, no quiero dejar que SQL genere el Guid).
¿Cuál es la mejor práctica para crear Claves primarias basadas en GUID, para evitar los supuestos golpes de rendimiento asociados con este enfoque?
Respuestas:
Los GUID pueden parecer una opción natural para su clave principal, y si realmente debe hacerlo, probablemente podría argumentar que la usará para la CLAVE PRIMARIA de la tabla. Lo que recomiendo encarecidamente que no haga es usar la columna GUID como clave de agrupación , que SQL Server hace de manera predeterminada, a menos que se lo indique específicamente.
Realmente necesitas mantener dos problemas separados:
la clave primaria es una construcción lógica, una de las claves candidatas que identifica de manera única y confiable cada fila de su tabla. Esto puede ser cualquier cosa, realmente, un
INT
, unGUID
, una cadena, elija lo que tenga más sentido para su escenario.la clave de agrupamiento (la columna o columnas que definen el "índice agrupado" en la tabla) - esto es algo relacionado con el almacenamiento físico , y aquí, un tipo de datos pequeño, estable y en constante aumento es su mejor elección,
INT
oBIGINT
como su Opción por defecto.Por defecto, la clave principal en una tabla de SQL Server también se usa como clave de agrupación, ¡pero eso no tiene por qué ser así! Personalmente, he visto ganancias masivas de rendimiento al dividir la Clave primaria / agrupada basada en GUID anterior en dos claves separadas: la clave primaria (lógica) en el GUID y la clave de agrupamiento (orden) en una
INT IDENTITY(1,1)
columna separada .Como Kimberly Tripp , la reina de la indexación, y otros han declarado muchas veces,
GUID
ya que la clave de agrupamiento no es óptima, ya que debido a su aleatoriedad, conducirá a una fragmentación masiva de páginas e índices y a un mal rendimiento en general.Sí, lo sé, hay
newsequentialid()
en SQL Server 2005 y versiones posteriores, pero incluso eso no es secuencial y completamente secuencial y, por lo tanto, también sufre los mismos problemas que elGUID
, solo que un poco menos prominente.Luego, hay otro problema a considerar: la clave de agrupación en una tabla se agregará a todas y cada una de las entradas de todos y cada uno de los índices no agrupados en su tabla, por lo que realmente desea asegurarse de que sea lo más pequeña posible. Por lo general, una
INT
con más de 2 mil millones de filas debería ser suficiente para la gran mayoría de las tablas, y en comparación con unaGUID
clave de agrupación, puede ahorrarse cientos de megabytes de almacenamiento en el disco y en la memoria del servidor.Cálculo rápido: usando
INT
vs.GUID
como clave principal y de agrupamiento:TOTAL: 25 MB frente a 106 MB , ¡y eso es solo en una sola mesa!
Algo más para pensar: cosas excelentes de Kimberly Tripp: léelo, léelo de nuevo, ¡digerirlo! Es el evangelio de indexación de SQL Server, de verdad.
PD: por supuesto, si se trata de unos pocos cientos o miles de filas, la mayoría de estos argumentos realmente no tendrán un gran impacto en usted. Sin embargo: si entras en las decenas o cientos de miles de filas, o comienzas a contar en millones, entonces esos puntos se vuelven cruciales y muy importantes de entender.
Actualización: si desea tener su
PKGUID
columna como su clave principal (pero no su clave de agrupación) y otra columnaMYINT
(INT IDENTITY
) como su clave de agrupación, use esto:Básicamente: solo tiene que decir explícitamente la
PRIMARY KEY
restricción que esNONCLUSTERED
(de lo contrario, se crea como su índice agrupado, de forma predeterminada), y luego crea un segundo índice que se define comoCLUSTERED
Esto funcionará, y es una opción válida si tiene un sistema existente que necesita ser "rediseñado" para su rendimiento. Para un nuevo sistema, si comienzas desde cero y no estás en un escenario de replicación, siempre elegiría
ID INT IDENTITY(1,1)
como mi clave principal agrupada, ¡mucho más eficiente que cualquier otra cosa!fuente
DATETIME
por ejemplo, NO son útiles para una clave de agrupación, ya que solo tienen una precisión de 3,33 ms y, por lo tanto, pueden existir duplicados. Por lo tanto, en tal caso, * todavía necesita unINT IDENTITY
lugar, por lo tanto, normalmente lo uso de manera predeterminada, ya que desde mis más de 20 años de experiencia, una clave natural realmente utilizable casi nunca existe ...He estado usando GUID como PK desde 2005. En este mundo de bases de datos distribuidas, es absolutamente la mejor manera de combinar datos distribuidos. Puede disparar y olvidar tablas de fusión sin la preocupación de que las entradas coincidan en tablas unidas. Las combinaciones de GUID se pueden copiar sin ninguna preocupación.
Esta es mi configuración para usar GUID:
PK = GUID. Los GUID se indexan de forma similar a las cadenas, por lo que las tablas de filas altas (más de 50 millones de registros) pueden necesitar particiones de tabla u otras técnicas de rendimiento. SQL Server se está volviendo extremadamente eficiente, por lo que los problemas de rendimiento son cada vez menos aplicables.
PK Guid es un índice NO agrupado. Nunca agrupe el índice de un GUID a menos que sea NewSequentialID. Pero incluso entonces, un reinicio del servidor provocará interrupciones importantes en el pedido.
Agregue ClusterID Int a cada tabla. Este es su índice agrupado ... que ordena su mesa.
Unirme a ClusterIDs (int) es más eficiente, pero trabajo con 20-30 millones de tablas de registros, por lo que unirme a GUIDs no afecta visiblemente el rendimiento. Si desea un rendimiento máximo, use el concepto ClusterID como clave principal y únase a ClusterID.
Aquí está mi tabla de correo electrónico ...
fuente
Actualmente estoy desarrollando una aplicación web con EF Core y aquí está el patrón que uso:
Todas mis clases (tablas) y un int PK y FK. Tengo una columna adicional con el tipo Guid (generado por el constructor de c #) con un índice no agrupado.
Todas las uniones de la tabla dentro de EF se administran a través de las teclas int, mientras que todo el acceso desde el exterior (controladores) se realiza con las Guías.
Esta solución permite no mostrar las claves int en las URL pero mantiene el modelo ordenado y rápido.
fuente
Si usa GUID como clave principal y crea un índice agrupado, le sugiero que use el valor predeterminado NEWSEQUENTIALID ()
fuente
Este enlace lo dice mejor de lo que podría y me ayudó en la toma de decisiones. Por lo general, opto por un int como clave principal, a menos que tenga una necesidad específica de no hacerlo y también dejo que el servidor SQL genere / mantenga automáticamente este campo a menos que tenga alguna razón específica para no hacerlo. En realidad, las preocupaciones de rendimiento deben determinarse en función de su aplicación específica. Aquí hay muchos factores en juego, que incluyen, entre otros, el tamaño de base de datos esperado, la indexación adecuada, la consulta eficiente y más. Aunque las personas pueden estar en desacuerdo, creo que en muchos escenarios no notará una diferencia con ninguna de las opciones y debe elegir qué es más apropiado para su aplicación y qué le permite desarrollarse más fácil, más rápido y de manera más efectiva (si nunca completa la aplicación) ¿Qué diferencia hace el resto :).
https://web.archive.org/web/20120812080710/http://databases.aspfaq.com/database/what-should-i-choose-for-my-primary-key.html
PD: No estoy seguro de por qué usarías un PK compuesto o qué beneficio crees que te daría.
fuente
La mayoría de las veces no debe usarse como la clave principal para una tabla porque realmente afecta el rendimiento de la base de datos. enlaces útiles sobre el impacto de GUID en el rendimiento y como clave principal.
fuente
Tener identificaciones secuenciales hace que MUCHO sea más fácil para un pirata informático o minero de datos comprometer su sitio y sus datos. Tenga eso en cuenta al elegir un PK para un sitio web.
fuente