Tablas de división en MySQL. ¿Buena práctica?

14

Empecé a trabajar en un proyecto existente y el desarrollador anterior había dividido una tabla en 10 tablas separadas con esquemas idénticos pero con datos diferentes.

Las tablas se ven así:

[tableName_0]
[tableName_1]
[tableName_2]
[tableName_3]
[tableName_4]
[tableName_5]
[tableName_6]
[tableName_7]
[tableName_8]
[tableName_9]

La clave primaria es un idcampo entero . La aplicación utiliza un algoritmo hash ( idmod 10) para saber a qué tabla acceder cuando se realizan búsquedas. Por ejemplo id= 10 resultaría en [tableName_0].

Combinadas, las tablas tienen probablemente 100,000 filas y la tasa de crecimiento es relativamente baja.

Entonces, mi pregunta es si esta es o no una solución viable o incluso si es una buena práctica en cualquier situación. Mi teoría es presionar para que se combinen, ya que facilitará las cosas en cuanto a UNIONs, etc. La desventaja principal es cambiar todo el código de la aplicación y si vale la pena a largo plazo.

Toronja rosa
fuente

Respuestas:

16

Creo que todos están complicando demasiado esto. El punto clave aquí es:

Combinadas, las tablas tienen probablemente 100,000 filas y la tasa de crecimiento es relativamente baja.

Este es un pedazo de pastel para cualquier RDBMS para manejar. Vaya con una tabla, indexe correctamente y considere que es un problema resuelto.

No necesita considerar la partición, ya sea "casera" o de otro tipo, hasta que comience a manejar volúmenes de datos extremadamente grandes, piense en miles de millones de filas y más.

Nick Chammas
fuente
3

Puede usar tablas de fusión, sin embargo, son más anticuadas de las versiones 4.x. Dado que su aplicación está particionada manualmente, ya sea a) está ejecutando una versión realmente antigua ob) el desarrollador original no estaba al tanto de las particiones de tabla.

En resumen, si está ejecutando 5.1+ puede dejar que mysql haga esta partición por usted. Consulte http://dev.mysql.com/doc/refman/5.1/en/partitions.html. Si está utilizando 5.5, debe verificar esos documentos específicos, ya que encontrará algunas diferencias.

Hay muchas ventajas en la partición. Sin embargo, realmente depende del conjunto de datos disponible, los patrones de acceso y cómo se indexará. Además, tenga en cuenta que mis siguientes comentarios están en el contexto de la partición mysql 5+, NO en las tablas anteriores de MySql Merge; aunque a veces se discuten en términos de particiones.

Algunos ejemplos:

  • Hebillado directo (o hashing) basado en la clave de búsqueda de acceso frecuente. Si casi siempre está buscando una clave primaria u otra clave única, entonces mysql puede reducir el espacio de búsqueda en función de cuántas particiones tenga. Sin embargo, tenga en cuenta que esto puede ser perjudicial si particiona por una clave y luego busca con frecuencia por otra clave. Si busca por una clave, los datos no están particionados, entonces debe hacer MÁS búsquedas en las búsquedas (una para cada partición, b / c, francamente, no sabe dónde están los datos)
  • Considere situaciones en las que tiene un conjunto temporal de registros que crece por fecha y elimina periódicamente el mes anterior. Si está particionando por fecha, simplemente puede soltar una partición que es tan rápida como soltar una tabla, sin importar cuán grande sea. Si tuviera que podar una tabla de este tipo por fechas, tendría que emitir una o más consultas DELETE donde se elimine cada fila individual. La desventaja de esto es que mysql no crea automáticamente nuevas particiones una vez que haya alcanzado la fecha máxima que ha contado en este escenario; necesita secuencias de comandos de mantenimiento adicionales creadas en su parte para agregar particiones cuando sean necesarias.
  • Si está utilizando las comprobaciones myisam y las recuperaciones son mucho más rápidas. Considere una mesa myisam 100G. Si desea recuperar una tabla bloqueada, necesitaría al menos aproximadamente 100G de espacio libre en disco. Si se particionó en 10 trozos diferentes de igual tamaño, entonces solo necesita 10G de espacio (y menos memoria key_sort_buffer para una recuperación rápida); pero necesitaría hacer una iteración para cada partición.

En resumen, el enfoque general de las tablas de particionamiento puede ofrecer muchos beneficios. Sin embargo, no es una bala mágica que se aplique a ciegas sin tener en cuenta los patrones de acceso y cómo exactamente está particionando.

Me imagino situaciones en las que la partición deseada es muy específica de la aplicación y sería más adecuada para tener esa lógica en la capa de la aplicación. Sin embargo, dada su descripción directa del módulo 10, este no parece ser el caso.

EDITAR

Al escribir mi descripción, olvidé que dijiste que tu tabla tiene 100K filas. Sin el esquema completo de su tabla y su longitud promedio de fila, es difícil decirlo con certeza, pero en general eso suena de tamaño mediano incluso para hardware modesto. Al mismo tiempo, si no está causando problemas como está ahora o en el futuro previsible, no pierda tiempo e introduzca riesgos al cambiarlo.

atxdba
fuente
3

Lo que el desarrollador anterior ha hecho por usted es construir su propia implementación de partición por hash. MySQL literalmente admite esto de forma nativa desde MySQL 5.1:

http://dev.mysql.com/doc/refman/5.1/en/partitions-hash.html

No puedo pensar en una buena razón para implementar su propia partición por hash en lugar de confiar en la versión nativa [1]. Realizar cambios de esquema será una pesadilla.

También rara vez recomiendo partición por hash (la implementación nativa). Creo que sería útil si pudiera usarlo para buscar en paralelo cada una de las particiones a la vez (lo que MySQL no hará). Si necesita buscar en varias particiones, el esquema que ha descrito a menudo será mucho más lento.

[1] Sin embargo, para algunos de los otros tipos de particionamiento puede tener sentido rodar su propia partición. MySQL te obliga a que tu clave de partición sea parte de tu clave principal y de todos los índices únicos.

Morgan Tocker
fuente
2

En respuesta a la pregunta:

es si esta es o no una solución viable

En mi humilde opinión, esto parece una sobrecarga innecesaria. Simplemente puede indexar y particionar una sola tabla correctamente a menos que haya otra información que no se revela en la descripción.

En respuesta a la pregunta:

... si es una buena práctica en cualquier situación

En mi humilde opinión, el fragmentación vertical puede tener sentido según el contexto. Cuando veo esto, generalmente está en algún tipo de formulario de registro. Supongamos que estamos usando esto para los registros del servidor web y queremos particionar por mes. En lugar de alterar una tabla existente en su lugar todos los días, podríamos crear una nueva tabla todos los días y registrar filas en esa tabla.

Por ejemplo, imagina que una tabla de registro web puede tomar la forma:

datetime TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
uri VARCHAR(1024),
host VARCHAR(255),
user_agent VARCHAR(255),
etc...

Su solución crea tablas según sea necesario en la base de datos de weblog:

weblogs.20120301
weblogs.20120302
weblogs.20120303

etc.

De esta manera, los datos permanecen mantenibles y buscables. La extracción se convierte en un proceso periódico normal. Las operaciones continuas no están bloqueadas por operaciones en datos más antiguos.

En el escenario que has presentado, estás encerrado en una estructura de todos modos, entonces, ¿por qué no usar una sola tabla optimizada para este propósito? El almacenamiento de filas basado en algoritmos parece incompleto y propenso a errores.

randomx
fuente
0

Si una consulta apunta a datos enormes, la división de datos por condiciones de consulta tendría una mejora notable en el rendimiento. Pero tal división, como has visto, plantea algunos problemas de programación.

Entonces la pregunta es: ¿vale la pena dividir el rendimiento o dañar el rendimiento?

Si tiene una transacción que necesita bloquear varias filas en varias tablas y tiene problemas (por ejemplo, punto muerto o tiempo de espera de transacción), puede combinarlas en una sola tabla y reescribir el SQL para reparar los problemas.

Cuando pienso en dividir la tabla, solía considerar el equilibrio entre la ganancia de rendimiento y la complejidad de la programación.

En su situación, la modificación del código existente puede ser una solución a largo plazo para facilitar el mantenimiento del código. Sugeriría un intento de meta-programación. Por ejemplo, usando StringTemplate para generar SQL dinámicamente. Me gusta generar SQL desde el motor de metaprogramación si la modificación del código existente es demasiado difícil.

Mike Lue
fuente
0

Cuando necesite almacenar archivos en una tabla, usar esta metodología ayuda a exportar, reparar y restaurar.

Tengo tablas con> 30 Gb particionadas en 10 tablas. Estas tablas solo tienen ID - BLOB y para mí es fácil de mantener. Y uso MyISAM para guardar el búfer INNODB.

Marcelo Bus
fuente