Ya tengo algunos millones de filas en mi base de datos. No sabía sobre el tipo de datos UUID de PostgreSQL cuando diseñé mi esquema.
Una de las tablas tiene 16 millones de filas (aproximadamente de 3,5 millones a 4 millones de registros por fragmento), que crece a unos 500 000 registros por día. Todavía tengo el lujo de bajar el sistema de producción durante unas horas si es necesario. No tendré este lujo en una o dos semanas.
Mi pregunta es, ¿valdrá la pena hacerlo? Me pregunto sobre el rendimiento de JOIN, el uso del espacio en disco (el volcado gzip'd completo es 1.25 GiB), cosas de esa naturaleza.
El esquema de la tabla es:
# \d twitter_interactions
Table "public.twitter_interactions"
Column | Type | Modifiers
-------------------------+-----------------------------+-----------
interaction_id | character(36) | not null
status_text | character varying(1024) | not null
screen_name | character varying(40) | not null
twitter_user_id | bigint |
replying_to_screen_name | character varying(40) |
source | character varying(240) | not null
tweet_id | bigint | not null
created_at | timestamp without time zone | not null
Indexes:
"twitter_interactions_pkey" PRIMARY KEY, btree (interaction_id)
"twitter_interactions_tweet_id_key" UNIQUE, btree (tweet_id)
"index_twitter_interactions_on_created_at" btree (created_at)
"index_twitter_interactions_on_screen_name" btree (screen_name)
Triggers:
insert_twitter_interactions_trigger BEFORE INSERT ON twitter_interactions FOR EACH ROW EXECUTE PROCEDURE twitter_interactions_insert_trigger()
Number of child tables: 9 (Use \d+ to list them.)
fuente
No soy una persona de postgres en ningún sentido de la imaginación, pero según lo que sé de SQL Server, cuantas más filas quepa en una página de datos, mejor rendimiento tendrá (la lectura de datos del disco suele ser operación más cara). Por lo tanto, pasar de un campo ancho de 36 ish 1 byte a 16 byte GUID parece un ahorro de costos directo. Cuantas menos lecturas pueda incurrir, más rápido podrá devolver resultados. Todo esto, por supuesto, supone que un GUID / UUID satisface las necesidades comerciales de la tabla. Si un UUID lo satisface, ¿sería un bigint ? Eso afeitaría aún más su almacenamiento cuesta otros 8 bytes por fila.
Editar 1
Para los datos de personajes en Postgres, hay un costo de almacenamiento adicional para ellos. Las cadenas cortas, de menos de 127 bytes tienen una sobrecarga de 1 byte, mientras que cualquier cosa más larga tiene 4 bytes, que es cómo el segundo encuestado obtuvo un costo de 40 bytes para un campo de 36 bytes. Pero también hay una opción para la compresión de cadenas, por lo que tal vez no cueste los 40 totales. No puedo decir cuál sería el costo final, pero los fundamentos permanecen: cualquier cosa de más de 16 bytes aumentará el costo de almacenamiento, tomará más tiempo leer de y consumir más memoria.
fuente
Además del problema del espacio, tenga en cuenta que tendrá que cambiar cada tabla para usar el tipo de datos correcto o su rendimiento de unión se verá afectado.
fuente
Además del ahorro en tamaño de datos e índices (como lo han dicho otros), que se traduce en ahorros de E / S, lo que debe considerar es cómo generará nuevos valores
interaction_id
y cuál será el impacto en el índices y condiciones de consulta (uniones).Para el índice, será más pequeño, sin embargo, si muchas de sus consultas usan escaneos de índice, cambiar a UUID podría hacer que los escaneos de índice sean imposibles (dependiendo de cómo generará UUID) y
bigint
podría ser una opción mucho mejor.Finalmente, como el impacto real en el rendimiento depende también de sus patrones de uso y distribución de datos, debe ejecutar pruebas y tener un entorno de desarrollo y prueba en el que pueda probar sus cambios.
Esto le dará una respuesta mucho más exacta sobre el impacto en el rendimiento.
fuente