¿Puede MySQL realizar consultas de forma razonable en miles de millones de filas?


283

Estoy planeando almacenar escaneos desde un espectrómetro de masas en una base de datos MySQL y me gustaría saber si almacenar y analizar esta cantidad de datos es remotamente factible. Sé que el rendimiento varía enormemente según el entorno, pero estoy buscando el orden aproximado de magnitud: ¿las consultas demorarán 5 días o 5 milisegundos?

Formato de entrada

Cada archivo de entrada contiene una sola ejecución del espectrómetro; cada corrida se compone de un conjunto de escaneos, y cada escaneo tiene una matriz ordenada de puntos de datos. Hay un poco de metadatos, pero la mayoría del archivo se compone de matrices de 32 o 64 bits ints o flotantes.

Sistema host

| ---------------- + ------------------------------- |
El | OS | Windows 2008 de 64 bits |
El | Versión MySQL | 5.5.24 (x86_64) |
El | CPU | 2x Xeon E5420 (8 núcleos en total) |
El | RAM | 8GB |
El | Sistema de archivos SSD | 500 GiB |
El | RAID HDD | 12 TiB |
| ---------------- + ------------------------------- |

Hay algunos otros servicios que se ejecutan en el servidor con un tiempo de procesador insignificante.

Estadísticas de archivo

| ------------------ + -------------- |
El | número de archivos | ~ 16,000 |
El | tamaño total | 1.3 TiB |
El | tamaño min | 0 bytes |
El | tamaño máximo | 12 GiB |
El | media | 800 MiB |
El | mediana | 500 MiB |
El | puntos de datos totales | ~ 200 mil millones |
| ------------------ + -------------- |

El número total de puntos de datos es una estimación muy aproximada.

Esquema propuesto

Estoy planeando hacer las cosas "bien" (es decir, normalizar los datos como locos) y, por lo tanto, tendría una runstabla, una spectratabla con una clave foránea runsy una datapointstabla con una clave foránea spectra.

La pregunta de 200 mil millones de puntos de datos

Voy a analizar múltiples espectros y posiblemente incluso múltiples ejecuciones, lo que dará como resultado consultas que podrían tocar millones de filas. Suponiendo que indexo todo correctamente (que es un tema para otra pregunta) y no estoy tratando de mezclar cientos de MiB en la red, ¿es remotamente posible que MySQL maneje esto?

información adicional

Los datos de escaneo provendrán de archivos en formato mzML basado en XML . La carne de este formato está en los <binaryDataArrayList>elementos donde se almacenan los datos. Cada exploración produce> = 2 <binaryDataArray>elementos que, tomados en conjunto, forman una matriz bidimensional (o más) de la forma [[123.456, 234.567, ...], ...].

Estos datos son de escritura única, por lo que el rendimiento de la actualización y la seguridad de las transacciones no son una preocupación.

Mi plan ingenuo para un esquema de base de datos es:

runs mesa

El | nombre de columna | tipo |
| ------------- + ------------- |
El | id | CLAVE PRIMARIA |
El | hora_inicio | TIMESTAMP |
El | nombre | VARCHAR |
| ------------- + ------------- |

spectra mesa

El | nombre de columna | tipo |
| ---------------- + ------------- |
El | id | CLAVE PRIMARIA |
El | nombre | VARCHAR |
El | indice | INT |
El | espectro_tipo | INT |
El | representación | INT |
El | run_id | CLAVE EXTRANJERA |
| ---------------- + ------------- |

datapoints mesa

El | nombre de columna | tipo |
| ------------- + ------------- |
El | id | CLAVE PRIMARIA |
El | espectro_id | CLAVE EXTRANJERA |
El | mz | DOBLE |
El | num_counts | DOBLE |
El | indice | INT |
| ------------- + ------------- |

¿Es esto razonable?


Entonces, como habrás podido inferir, soy el programador, no el biólogo en el laboratorio, por lo que no conozco la ciencia tan bien como los científicos reales.

Aquí hay una gráfica de un solo espectro (escaneo) del tipo de datos con los que me ocuparé:

Captura de pantalla del visor

El objetivo del software es descubrir dónde y cuán significativos son los picos. Usamos un paquete de software patentado para resolver esto ahora, pero queremos escribir nuestro propio programa de análisis (en R) para saber qué diablos está pasando debajo de las hojas. Como puede ver, la gran mayoría de los datos no son interesantes, pero no queremos arrojar datos potencialmente útiles que nuestro algoritmo perdió. Una vez que tengamos una lista de picos probables con los que estamos satisfechos, el resto de la tubería utilizará esa lista de picos en lugar de la lista sin procesar de puntos de datos. Supongo que sería suficiente almacenar los puntos de datos sin procesar como un gran blob, para que se puedan volver a analizar si es necesario, pero mantenga solo los picos como entradas de base de datos distintas. En ese caso, solo habría un par de docenas de picos por espectro, por lo que las cosas locas de escalado no deberían



8
Como se trata de datos brutos de espectrómetro de masas de sondeo A / D, parece realmente tonto almacenarlos en la base de datos. Tomaría mis datos en bruto, los volcaría, los procesaría y almacenaría los RESULTADOS procesados ​​en una base de datos. Los resultados serían (a) formas de onda almacenadas una forma de onda por fila, (b) otros datos asociados con esas formas de onda, como curvas de calibración, y (c) filas de resultados en la base de datos. Esto reduciría miles de millones de filas de hinchazón de su diseño. Cuando desee volver a ejecutar un análisis inicial, efectivamente estaría editando algunos parámetros, ejecutando una operación de cálculo gigante y almacenando los nuevos resultados en la base de datos.
Warren P

Respuestas:


115

No estoy muy familiarizado con sus necesidades, pero tal vez almacenar cada punto de datos en la base de datos es un poco exagerado. Suena casi como adoptar el enfoque de almacenar una biblioteca de imágenes almacenando cada píxel como un registro separado en una base de datos relacional.

Como regla general, el almacenamiento de datos binarios en bases de datos es incorrecto la mayor parte del tiempo. Por lo general, hay una mejor manera de resolver el problema. Si bien no es inherentemente incorrecto almacenar datos binarios en una base de datos relacional, a menudo las desventajas superan las ganancias. Las bases de datos relacionales, como alude el nombre, son las más adecuadas para almacenar datos relacionales. Los datos binarios no son relacionales. Agrega tamaño (a menudo de manera significativa) a las bases de datos, puede afectar el rendimiento y puede dar lugar a preguntas sobre el mantenimiento de instancias de MySQL de mil millones de registros. La buena noticia es que hay bases de datos especialmente adecuadas para almacenar datos binarios. ¡Uno de ellos, aunque no siempre es evidente, es su sistema de archivos! Simplemente cree un directorio y una estructura de nombres de archivos para sus archivos binarios,

Otro enfoque sería usar un sistema de almacenamiento basado en documentos para sus datos de puntos de datos (y quizás espectros), y usar MySQL para las ejecuciones (o quizás colocar las ejecuciones en la misma base de datos que las demás).


55
¿Por qué se considera incorrecto almacenar datos binarios en una base de datos? (Preguntando en parte porque tengo curiosidad, pero también porque puedo pensar en un caso de uso para ello.)

15
Si los datos binarios no tienen valor individualmente, no deben almacenarse como una fila única. El píxel 500x325 en una imagen es irrelevante.

1
Ese es un muy buen punto. Probablemente deberíamos mantener los archivos sin formato en caso de que necesitemos sacar cosas nuevamente más tarde, pero la analogía para almacenar imágenes es excelente. Nunca necesitaremos acceso a cada punto de datos (a menos que estemos rehaciendo la extracción máxima), por lo que simplemente sería mejor almacenar la información estadística extraída.
haxney

107

Una vez trabajé con una base de datos MySQL muy grande (Terabyte +). La mesa más grande que tuvimos fue literalmente más de mil millones de filas. Esto estaba usando MySQL 5.0, por lo que es posible que las cosas hayan mejorado.

Funcionó. MySQL procesó los datos correctamente la mayor parte del tiempo. Sin embargo, fue extremadamente difícil de manejar. (Si desea disponibilidad de nivel sigma seis con un terabyte de datos, no use MySQL. Éramos una startup que no tenía DBA y fondos limitados).

Solo hacer copias de seguridad y almacenar los datos fue un desafío. Nos llevaría días restaurar la mesa si fuera necesario.

Tuvimos numerosas mesas en el rango de 10-100 millones de filas. Cualquier unión significativa a las mesas consumía demasiado tiempo y tomaría una eternidad. Así que escribimos procedimientos almacenados para 'recorrer' las tablas y unir procesos con rangos de 'id' De esta manera, procesaríamos los datos de 10 a 100,000 filas a la vez (Unirse contra los ID de 1-100,000 y luego 100,001-200,000, etc.). Esto fue significativamente más rápido que unirse contra toda la mesa.

Usar índices en tablas muy grandes que no están basadas en la clave primaria también es mucho más difícil. Mysql 5.0 almacena índices en dos partes: almacena índices (que no sean el índice primario) como índices de los valores de la clave primaria. Por lo tanto, las búsquedas indexadas se realizan en dos partes: primero MySQL va a un índice y extrae de él los valores de clave principal que necesita encontrar, luego realiza una segunda búsqueda en el índice de clave principal para encontrar dónde están esos valores.

La red de esto es que para tablas muy grandes (1-200 millones de filas más) la indexación de tablas es más restrictiva. Necesita menos índices, más simples. E incluso hacer declaraciones de selección simples que no están directamente en un índice puede que nunca vuelvan. Donde las cláusulas deben golpear índices u olvidarse de él.

Pero dicho todo esto, las cosas realmente funcionaron. Pudimos usar MySQL con estas tablas muy grandes y hacer cálculos y obtener respuestas correctas.

Intentar hacer un análisis en 200 mil millones de filas de datos requeriría hardware de muy alta gama y mucha mano y paciencia. Mantener una copia de seguridad de los datos en un formato desde el que pueda restaurar sería un trabajo importante.

Estoy de acuerdo con la respuesta de srini.venigalla de que normalizar los datos como locos puede no ser una buena idea aquí. Hacer uniones en varias tablas con esa cantidad de datos lo abrirá al riesgo de clasificaciones de archivos, lo que podría significar que algunas de sus consultas nunca volverían. La desnormalización con teclas enteras simples le daría una mejor oportunidad de éxito.

Todo lo que teníamos era InnoDB. Con respecto a MyISAM vs. InnoDB: Lo principal sería no mezclar los dos. Realmente no puede optimizar un servidor para ambos debido a la forma en que MySQL almacena en caché las claves y otros datos. Elija uno u otro para todas las tablas en un servidor si puede. MyISAM puede ayudar con algunos problemas de velocidad, pero puede no ayudar con el trabajo general de DBA que debe hacerse, lo que puede ser mortal.


1
MySQL mejoró mucho en el departamento de índices (...) desde 5.0. Sería interesante ver cómo se comporta ahora.
Anillo Ø

70

normalizando los datos como locos

Normalizar los datos como locos puede no ser la estrategia correcta en este caso. Mantenga sus opciones abiertas almacenando los datos tanto en forma Normalizada como también en forma de vistas materializadas muy adecuadas para su aplicación. La clave en este tipo de aplicaciones NO es escribir consultas ad hoc. El modelado de consultas es más importante que el modelado de datos. Comience con sus consultas de destino y trabaje hacia el modelo de datos óptimo.

Is this reasonable?

También crearía una tabla plana adicional con todos los datos.

run_id | spectrum_id | data_id | <data table columns..> |

Usaré esta tabla como la fuente principal de todas las consultas. La razón es para evitar tener que hacer uniones. Las uniones sin indexación harán que su sistema sea muy inutilizable, y tener índices en archivos tan grandes será igualmente terrible.

La estrategia es, primero consultar en la tabla anterior, volcar los resultados en una tabla temporal y unirse a la tabla temporal con las tablas de búsqueda de Run and Spectrum y obtener los datos que desea.


¿Ha analizado sus necesidades de escritura frente a las necesidades de lectura? Será muy tentador deshacerse de SQL e ir a mecanismos de almacenamiento de datos no estándar. En mi opinión, debería ser el último recurso.

Para acelerar las velocidades de escritura, es posible que desee probar el método Handler Socket. Percona, si mal no recuerdo, empaqueta Handler Socket en su paquete de instalación. (¡sin relación con Percona!)

http://yoshinorimatsunobu.blogspot.com/2010/10/using-mysql-as-nosql-story-for.html


33

La respuesta corta es un sí calificado: a medida que aumenta el número de filas, el esquema preciso, los tipos de datos y las operaciones que elija aumentan en importancia.

Cuánto normaliza sus datos depende de las operaciones que planea realizar en los datos almacenados. En particular, su tabla de 'puntos de datos' parece problemática: ¿planea comparar el enésimo punto de un espectro dado con el enésimo de cualquier otro? Si no, almacenarlos por separado podría ser un error. Si sus puntos de datos no están solos sino que tienen sentido solo en el contexto de sus espectros asociados, no necesita una CLAVE PRIMARIA: una clave externa para los espectros y una columna 'n' (¿su columna 'índice'?) Será suficiente .

Defina las operaciones inter e intra-espectro que debe realizar y luego descubra la forma más económica de lograrlas. Si la igualdad es todo lo que se necesita, pueden estar desnormalizados, posiblemente con algunos metadatos estadísticos precalculados que ayudan a sus operaciones. Si realmente necesita acceso en SQL a puntos de datos individuales, asegúrese de reducir el tamaño de cada fila al mínimo número de campos y al tipo de datos más pequeño posible.

El MySQL más grande que he administrado personalmente fue ~ 100 millones de filas. En este tamaño, desea mantener sus filas y, por lo tanto, sus campos de tamaño fijo, esto permite que MySQL calcule eficientemente la posición de cualquier fila en la tabla multiplicando por el tamaño fijo de cada fila (piense en la aritmética del puntero), aunque los detalles exactos dependen del motor de almacenamiento que planee usar. Use MyISAM si puede salirse con la suya, lo que le falta en fiabilidad lo compensa en velocidad, y en su situación debería ser suficiente. Reemplace los campos de tamaño variable como VARCHAR con CHAR (n) y use RTRIM () en sus consultas de lectura.

Una vez que las filas de la tabla tienen un ancho fijo, puede reducir la cantidad de bytes evaluando cuidadosamente los tipos de datos enteros de MySQL (algunos de los cuales no son estándar). Cada ahorro de 1 byte que puede obtener al convertir un INT de 4 byte en un MEDIUMINT de 3 byte le ahorra ~ 1 MB por millón de filas, lo que significa menos E / S de disco y un almacenamiento en caché más efectivo. Utilice los tipos de datos más pequeños posibles con los que pueda salirse con la suya . Evalúe cuidadosamente los tipos de punto flotante y vea si puede reemplazar los DOBLES de 8 bytes con FLOAT de 4 bytes o incluso NUMÉRICOS de punto fijo de <8 bytes . Ejecute pruebas para asegurarse de que lo que elija no lo muerda más tarde.

Dependiendo de las propiedades esperadas de su conjunto de datos y las operaciones requeridas, puede haber ahorros adicionales en codificaciones más inusuales de sus valores (patrones / repeticiones esperados que pueden codificarse como un índice en un conjunto de valores, datos sin procesar que solo pueden contribuir significativamente a metadatos y descarte, etc.), aunque las optimizaciones exóticas, poco intuitivas y destructivas solo valen la pena cuando se ha probado cualquier otra opción.

Lo más importante, no importa lo que termine haciendo, no asuma que ha elegido el esquema perfecto y luego, ciegamente, comience a descargar 10 millones de registros. Los buenos diseños tardan en evolucionar. Cree un conjunto grande pero manejable (digamos, 1-5%) de datos de prueba y verifique la exactitud y el rendimiento de su esquema. Vea cómo se realizan las diferentes operaciones (http://dev.mysql.com/doc/refman/5.0/en/using-explain.html) y asegúrese de equilibrar su esquema para favorecer las operaciones más frecuentes.

¿Dije corto? Whoops De todos modos, ¡buena suerte!


23

Parece que la única razón para triturar los datos del punto de datos fuera del XML (en oposición a los metadatos como el tiempo y el tipo de ejecución) y en un formulario de base de datos es cuando está analizando los espectros en las matrices, es decir, tal vez encontrando todos corre con una cierta firma. Solo usted conoce su dominio del problema en este momento, pero esto podría ser similar al almacenamiento de música muestreada a 96 kHz con 1 muestra por fila. No estoy seguro de que el problema sea más el tamaño que la forma en que se usan los datos. La consulta a través de los datos sería equivalente a pedir la amplitud relativa de 2 minutos en la canción en todas las canciones de The Beatles. Si conoce el tipo de análisis que se pueden realizar, es muy posible que realizarlos en las señales y almacenarlos en los metadatos sobre la ejecución tenga más sentido.

Tampoco estoy seguro de si sus datos de origen son escasos. Es completamente posible que un espectro en la base de datos solo incluya entradas que no sean cero, mientras que el XML original sí incluye entradas cero, por lo que su número total de filas podría ser mucho menor que en los datos de origen.

Entonces, como muchas preguntas, antes de preguntar sobre MySQL manejando su modelo, dar un paso atrás y mirar el modelo y cómo se va a usar probablemente sea más apropiado que preocuparse por el rendimiento por el momento.


Después de revisar las actualizaciones de sus preguntas, creo que un modelo en el que los datos binarios se almacenan como BLOB o simplemente como un puntero al archivo es suficiente y trabajo en modificar su modelo para almacenar datos sobre los picos significativos que se han identificado cuando los datos se encuentran por primera vez. leer.


18

Ejecuto un servicio de análisis web con aproximadamente 50 servidores de bases de datos, cada uno con muchas tablas de más de 100 millones de filas, y varias que tienden a tener más de mil millones de filas, a veces hasta dos mil millones (en cada servidor).

El rendimiento aquí está bien. Son datos muy normalizados. Sin embargo, mi principal preocupación al leer esto es que superará los 4.200 millones de filas para estas tablas (tal vez no "ejecute" pero probablemente las otras dos), lo que significa que deberá usar BIGINT en lugar de INT para Las claves primarias / foráneas.

El rendimiento de MySQL con campos BIGINT en una columna indexada es ridículamente horrible en comparación con INT. Cometí el error de hacer esto una vez con una mesa que pensé que podría crecer más de este tamaño, y una vez que llegó a unos cientos de millones de filas, el rendimiento fue simplemente abismal. No tengo números en bruto, pero cuando digo malo, me refiero a Windows ME malo.

Esta columna fue la clave principal. Lo convertimos de nuevo para ser solo un INT y presto magico, el rendimiento fue bueno nuevamente.

Todos nuestros servidores en ese momento estaban en Debian 5 y con MySQL 5.0. Desde entonces, hemos actualizado a Debian 6 y Percona MySQL 5.5, por lo que las cosas pueden haber mejorado desde entonces. Pero según mi experiencia aquí, no, no creo que funcione muy bien.


17

Si funciona o no, siempre se encontrará con el mismo problema con un solo medio de almacenamiento monolítico: los discos son lentos. A 100 MB / s (bastante bueno para hacer girar medios) lleva solo 3 horas leer una tabla de 1TB; eso supone que ningún análisis o búsqueda u otros retrasos lo retrasen.

Es por eso que casi todas las instalaciones de "big data" utilizan algún tipo de almacén de datos distribuido. Puede gastar 8 veces más dinero construyendo una computadora súper increíble para ejecutar su DB, pero si tiene muchos datos que se pueden escanear en paralelo, casi siempre es mejor distribuir la carga en las 8 computadoras más baratas.

Proyectos como hadoop se construyeron específicamente para fines como este. Construye un clúster de un montón de computadoras económicas, distribuye los datos en todas ellas y las consulta en paralelo. Es solo una de media docena de soluciones construidas alrededor de esta misma idea, pero es muy popular.


13

Hm ... veo dos razones por las que elegirías este tipo de estructura de datos:

  • realmente necesita hacer cualquier punto de datos frente a cualquier consulta de punto de datos
  • tiene la intención de realizar toda su lógica en SQL

Ahora, sugeriría analizar detenidamente sus requisitos y verificar que al menos uno de los supuestos anteriores sea cierto. Si ninguno de los dos es cierto, simplemente está haciendo las cosas más lentas. Para este tipo de conjunto de datos, sugeriría primero averiguar cómo se espera que se acceda a los datos, qué tipo de precisión necesitará, etc., y luego diseñar su base de datos en torno a ellos.

PD: tenga en cuenta que necesitará al menos 36 + 5 bytes por punto de datos, por lo que con los puntos de datos 200B que deberían proporcionarle al menos 8.2 TB de espacio requerido.

PPS: No necesita la idcolumna en la datapointstabla, PRIMARY KEY (spectrum_id, index)probablemente sea suficiente (solo tenga cuidado con que indexpuede ser una palabra reservada)


12

EDITAR:

NO HAGA ESTO EN MYSQL CON DATOS ALMACENADOS EN UN SOLO DISCO. Solo leer esa cantidad de datos de un solo medio llevará horas. Necesita ESCALAR, NO ARRIBA.

Y debe desnormalizar sus datos si desea realizar un análisis de datos efectivo. No está diseñando un sistema en línea aquí. Desea agrupar números, diseñar en consecuencia.

Respuesta original debajo de la línea.


La respuesta variará dependiendo de sus consultas, MySQL puede no ser la mejor herramienta para este trabajo. Es posible que desee buscar una solución que pueda escalar "fuera" y no "arriba". Si está dispuesto a esforzarse, tal vez debería buscar una solución Map Reduce como Hadoop.

Si desea hacer más consultas ad-hoc, la solución BigQuery de Google puede ser adecuada para usted. Presentación relevante de Google I / O 2012: Crunching Big Data con BigQuery

Por lo tanto, la solución dependerá de si esto es algo único y si desea admitir razonablemente consultas ad hoc.


9

Nadie ha mencionado, por lo tanto, mi sugerencia. Eche un vistazo a las soluciones MySQL masivamente fragmentadas . Por ejemplo, vea esta presentación de tumblr de gran prestigio .

El concepto es:

  • En lugar de una base de datos extra grande
  • Utilice muchos pequeños que contengan partes de los datos originales.

Por lo tanto, puede escalar horizontalmente, en lugar de intentar mejorar el rendimiento vertical. BigTable y GFS de Google también están utilizando nodos baratos escalables horizontalmente para almacenar y consultar petabytes de datos.

Sin embargo, habrá problemas si necesita ejecutar consultas sobre diferentes fragmentos.


Si alguien está interesado, hice una aplicación de fragmentación hello-world hace un tiempo. Se discute aquí en una publicación de blog. Usé RavenDB y C # pero los detalles son irrelevantes y la idea es la misma.


7

¿En qué tipo de máquina se almacenarán los datos? ¿Es un dispositivo de almacenamiento compartido?

El último factor que determinará el tiempo de su consulta serán sus discos duros. Las bases de datos y sus optimizadores de consultas están diseñados para reducir la cantidad de E / S de disco tanto como sea posible. Dado que solo tiene 3 tablas, esto se hará de manera bastante confiable.

Las velocidades de lectura / escritura de un disco duro serán 200-300 veces más lentas que las velocidades de memoria. Busque discos duros con latencia muy rápida y velocidades de lectura y escritura rápidas. Si todos estos datos están en una unidad de 2 TB, es probable que espere mucho tiempo a que finalicen las consultas. La latencia del disco duro es de ~ 10-15 milisegundos, mientras que la latencia de la memoria es inferior a 10 nanosegundos. La latencia del disco duro puede ser 1000-2000x más lenta que la latencia de la memoria. El movimiento del brazo mecánico en el disco duro es lo MÁS LENTO en todo este sistema.

¿Cuánta RAM tienes? ¿16 GB? Digamos que le permite tener 32 registros. Tienes 16000 archivos. Si va a escanear linealmente todos los puntos de datos, podría terminar fácilmente con 5-10 segundos en tiempo de búsqueda solo. Entonces factor en la velocidad de transferencia de 50mb / s? Unas 7 horas. Además, los datos guardados temporalmente deberán almacenarse en el disco duro para dejar espacio para la lectura de nuevos datos.

Si está utilizando un dispositivo de almacenamiento compartido que está siendo utilizado activamente por otros usuarios ... su mejor opción será ejecutar todo por la noche.

Reducir la cantidad de consultas anidadas también ayuda. Las consultas anidadas dan como resultado tablas temporales que agotarán aún más su disco duro. Espero que tengas MUCHO espacio libre en tu disco duro.

La optimización de la consulta solo puede ver 1 consulta a la vez. Por lo tanto, las instrucciones de selección anidadas no se pueden optimizar. SIN EMBARGO, si sabe que una consulta anidada específica dará como resultado que se devuelva un pequeño conjunto de datos, consérvelo. La optimización de la consulta utiliza histogramas y suposiciones aproximadas; si sabe algo sobre los datos y la consulta, continúe y hágalo.

Cuanto más sepa sobre la forma en que se almacenan sus datos en el disco, más rápido podrá escribir sus consultas. Si todo se almacenó secuencialmente en la clave primaria, puede ser beneficioso ordenar las claves primarias devueltas de una consulta anidada. Además, si puede reducir el conjunto de conjuntos de datos que necesita analizar de antemano, hágalo. Dependiendo de su sistema, verá aproximadamente 1 segundo de transferencia de datos por archivo.

Si va a modificar los valores de Nombre (los varchars), lo cambiaría a un tipo de datos con un tamaño máximo, evitará la fragmentación y la compensación es solo unos pocos bytes más de memoria. Tal vez un NVARCHAR con 100 máximo.

En cuanto a los comentarios sobre desnormalizar la tabla. Creo que puede ser mejor simplemente almacenar los puntos de datos en grupos más grandes (tal vez como espectros) y luego hacer el análisis de datos en python o en un lenguaje que interactúa con la base de datos. A menos que sea un SQL-Wizard.


3
Usted enfatiza la gran diferencia en el disco duro frente a la latencia de la memoria, pero sus números están apagados por un factor de 1000. Si los discos duros tienen una latencia de alrededor de 10 ms, y la memoria de 10ns, las latencias no difieren en un factor de 1,000 sino en un factor de 1,000,000!
spectre256

6

Para mí, parece un escenario de uso en el que desea algo así como un "almacén de columnas relacionales" como se describe aquí .

Puedo estar malinterpretando el diseño, pero si se trata principalmente de una gran colección de matrices, almacenarlas en tablas orientadas a filas típicas significa que cada elemento es similar a un segmento. Si está interesado en mirar cortes de una manera típica, tiene sentido, pero podría ser menos eficiente si realmente está mirando columnas enteras a la vez.

Al recuperar las matrices, no solo es posible que no necesite unirlas con otra tabla resultante de su normalización, sino que puede recuperar la serie como una matriz en lugar de un hash.

Realmente puedo estar malinterpretando el problema, y ​​ni siquiera estoy sugiriendo una solución específica.

Aquí hay otra charla que puede ser relevante, incluso si no es realmente una solución actual o implementable.



5

Sí, pero...

He trabajado con tablas que tenían 2 mil millones de filas. Sin embargo, solo se esperaba que las consultas con PK fueran rápidas.

Lo más importante, el hardware tenía suficiente RAM para acomodar tablas enteras en la memoria. Cuando eso se convirtió en un problema (máximo en 96 GB en ese momento), optó por la partición vertical, manteniendo el tamaño de la tabla establecida en cada máquina lo suficientemente pequeño como para caber en la memoria. Además, las máquinas estaban conectadas a través de fibra de 10 Gb, por lo que el rendimiento de la red no era un gran problema.

Por cierto. su esquema se ve como algo, que podría encajar en la solución NoSQL, utilizando run_idcomo clave de hash para espectros y spectrum_idcomo clave de hash para puntos de datos.


4

He escrito sobre este tema en mi blog: http://www.tocker.ca/2013/10/24/improving-the-performance-of-large-tables-in-MySQL.html

Para repetir algunos de los puntos clave:

  • Los árboles B se degradan a medida que crecen y no caben en la memoria (MySQL no está solo aquí).
  • InnoDB tiene algunas características para ayudar a mantener el rendimiento (cambiar el almacenamiento en búfer; anteriormente llamado 'insertar búfer').
  • Particionar también puede ayudar.

En los comentarios de mi publicación, Tim Callaghan se vinculó a esto: http://www.tokutek.com/resources/benchmark-results/benchmarks-vs-innodb-hdds/#iiBench

Lo que muestra la inserción de 1 mil millones de filas utilizando el punto de referencia iibench.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.