Estoy después de una confirmación de esta idea para arreglar una base de datos de bajo rendimiento o una mejor sugerencia si alguien tiene una. Siempre abierto a mejores sugerencias.
Tengo una base de datos muy grande (más de 20 millones de registros que crecen aproximadamente 1/2 millón por día) que usan GUID como PK.
Un descuido de mi parte, pero el PK está agrupado en el servidor SQL y está causando problemas de rendimiento.
El motivo de un guid: esta base de datos está parcialmente sincronizada con otras 150 bases de datos, por lo que la PK debe ser única. La sincronización no es administrada por SQL Server, sino que hay un proceso personalizado creado que mantiene los datos sincronizados para los requisitos del sistema, todo basado en ese GUID.
Cada una de las 150 bases de datos remotas no almacena los datos completos como se almacenan en la base de datos central de SQL. solo almacenan un subconjunto de los datos que realmente requieren, y los datos que requieren no son exclusivos para ellos (10 de las 150 bases de datos pueden tener algunos de los mismos registros de las bases de datos de otros sitios, por ejemplo, comparten). Además, los datos se generan en los sitios remotos, no en el punto central, de ahí la necesidad de los GUID.
La base de datos central se usa no solo para mantener todo sincronizado, sino que las consultas de más de 3000 usuarios se ejecutarán en esa gran base de datos fragmentada. Este ya es un gran problema en las pruebas iniciales.
Afortunadamente, todavía no estamos en vivo, por lo que puedo hacer cambios y desconectar las cosas si es necesario, que es al menos algo.
El rendimiento de las bases de datos remotas no es un problema: los subconjuntos de datos son bastante pequeños y la base de datos generalmente nunca supera el tamaño de 1 GB en total. Los registros se retroalimentan al sistema principal con bastante regularidad y se eliminan de los BD más pequeños cuando ya no son necesarios.
El rendimiento de la base de datos central que es el guardián de todos los registros es lamentable, debido a un GUID agrupado como clave principal para esa cantidad de registros. La fragmentación del índice está fuera de los gráficos.
Entonces, mi intención de solucionar el problema de rendimiento es Crear una nueva columna: IDENTIDAD BIGINT sin firmar (1,1) y luego cambiar el PK agrupado de la columna BIGINT de la tabla.
Crearía un índice único no agrupado en el campo GUID, que era la clave principal.
Las 150 bases de datos remotas más pequeñas no necesitan saber acerca de la nueva PK en la base de datos del Servidor SQL Central: se utilizará exclusivamente para organizar los datos en la base de datos y detener el mal rendimiento y la fragmentación.
¿Funcionaría y mejoraría el rendimiento de la base de datos central de SQL y evitaría un futuro infierno de fragmentación del índice (hasta cierto punto)? ¿O me he perdido algo muy importante aquí que va a saltar y morderme y causar aún más dolor?
fuente
int
en 4255 días (11.5 años). Si lo hiciera, solo te culparía en 11.5 años;)Respuestas:
Ciertamente, NO necesita agruparse en el GUID. Si tiene algo que le permitiría identificar de manera única los registros que no sean ese GUID, le sugiero que busque construir un índice único en ese otro campo y agrupar ese índice. De lo contrario, puede agruparse en otros campos, incluso utilizando índices no únicos. Sin embargo, el enfoque sería agrupar, sin embargo, facilita la división de sus datos y las consultas, por lo que, si tiene un campo de "región", o algo así, podría ser un candidato para su esquema de agrupación.
El problema con el cambio a a
BIGINT
sería adiciones a los datos de otras bases de datos e integración de su base de datos en la tienda central. Si esto no es una consideración, y nunca será una consideración, entonces síBIGINT
resolvería el problema del reequilibrio del índice muy bien.Detrás de escena, si no especifica un índice agrupado, SQL Server hace lo mismo: crea un campo de ID de fila y asigna todos los demás índices a ese. Entonces, al hacerlo usted mismo, lo está resolviendo tal como lo resolvería SQL.
fuente
Esa es una tarea difícil.
Permítanme sugerir un enfoque de intermediario.
Estaba teniendo problemas con System.Guid.NewGuid () generando guías aleatorias. (Estaba permitiendo que el cliente creara su propia guía, en lugar de confiar en la base de datos para crear una secuencial).
Una vez que me mudé a un UuidCreateSequential en el lado del cliente, mi rendimiento mejoró MUCHO, especialmente en INSERT.
Aquí está el código de cliente DotNet vudú. Estoy seguro de que empeñé desde algún lado:
IDEA ALTERNATIVA:
Si su base de datos principal y las bases de datos remotas están "vinculadas" (como en, sp_linkserver) ... entonces podría usar la base de datos principal como el "generador de uuid".
No quieres obtener el "uno por uno" de uuid, eso es demasiado charlatanería.
Pero podrías tomar un juego de uuid.
A continuación hay un código:
/ *
* /
fuente
Según su descripción, vaya con BIGINT. Sin embargo, el índice para GUID puede ser no único, ya que se supone que los GUID son globalmente únicos de todos modos.
fuente
Si GUID se almacena correctamente como identificador único, no debería haber problemas de rendimiento ... y si puede usar GUID secuencial aún mejor ...
También @mattytommo tiene un buen punto de aproximadamente 11.5 años con el uso de INT ...
fuente