Sé que sqlite no funciona bien con archivos de bases de datos extremadamente grandes, incluso cuando son compatibles (solía haber un comentario en el sitio web de sqlite que indica que si necesita archivos de más de 1 GB, puede considerar usar un rdbms empresarial. No lo encuentre más, podría estar relacionado con una versión anterior de sqlite).
Sin embargo, para mis propósitos, me gustaría tener una idea de lo malo que es realmente antes de considerar otras soluciones.
Estoy hablando de archivos de datos sqlite en el rango de varios gigabytes, desde 2 GB en adelante. Alguien tiene alguna experiencia con esto? ¿Algún consejo / idea?
database
performance
sqlite
Snazzer
fuente
fuente
Respuestas:
Así que hice algunas pruebas con sqlite para archivos muy grandes y llegué a algunas conclusiones (al menos para mi aplicación específica).
Las pruebas implican un único archivo sqlite con una sola tabla o varias tablas. Cada tabla tenía aproximadamente 8 columnas, casi todos enteros, y 4 índices.
La idea era insertar suficientes datos hasta que los archivos sqlite tuvieran aproximadamente 50 GB.
Mesa individual
Traté de insertar varias filas en un archivo sqlite con solo una tabla. Cuando el archivo tenía aproximadamente 7 GB (lo siento, no puedo ser específico sobre el recuento de filas) las inserciones tardaban demasiado. Había estimado que mi prueba para insertar todos mis datos tardaría aproximadamente 24 horas, pero no se completó incluso después de 48 horas.
Esto me lleva a concluir que una sola tabla sqlite muy grande tendrá problemas con las inserciones, y probablemente también con otras operaciones.
Supongo que esto no es una sorpresa, ya que la tabla se hace más grande, la inserción y actualización de todos los índices lleva más tiempo.
Tablas Múltiples
Luego intenté dividir los datos por tiempo en varias tablas, una tabla por día. Los datos para la tabla 1 original se dividieron en ~ 700 tablas.
Esta configuración no tuvo problemas con la inserción, no tardó más a medida que avanzaba el tiempo, ya que se creó una nueva tabla para cada día.
Problemas de vacío
Como lo señaló i_like_caffeine, el comando VACUUM es un problema cuanto más grande es el archivo sqlite. A medida que se realizan más inserciones / eliminaciones, la fragmentación del archivo en el disco empeorará, por lo que el objetivo es VACÍO periódicamente para optimizar el archivo y recuperar el espacio de archivo.
Sin embargo, como se señala en la documentación , se realiza una copia completa de la base de datos para hacer un vacío, lo que lleva mucho tiempo completarla. Por lo tanto, cuanto más pequeña sea la base de datos, más rápida será esta operación.
Conclusiones
Para mi aplicación específica, probablemente dividiré los datos en varios archivos db, uno por día, para obtener el mejor rendimiento de vacío y la velocidad de inserción / eliminación.
Esto complica las consultas, pero para mí, es una compensación valiosa poder indexar esta cantidad de datos. Una ventaja adicional es que solo puedo eliminar un archivo db completo para eliminar el valor de un día de datos (una operación común para mi aplicación).
Probablemente también tenga que monitorear el tamaño de la tabla por archivo para ver cuándo la velocidad se convertirá en un problema.
Es una pena que no parece haber un método de vacío incremental que no sea el vacío automático . No puedo usarlo porque mi objetivo para el vacío es desfragmentar el archivo (el espacio de archivo no es un gran problema), lo que el vacío automático no hace. De hecho, la documentación indica que puede empeorar la fragmentación, por lo que tengo que recurrir a hacer un vacío completo en el archivo periódicamente.
fuente
Estamos utilizando DBS de 50 GB + en nuestra plataforma. sin quejas funciona muy bien. ¡Asegúrate de estar haciendo todo bien! ¿Estás usando declaraciones predefinidas? * SQLITE 3.7.3
Aplique esta configuración (justo después de crear la base de datos)
Espero que esto ayude a otros, funciona muy bien aquí
fuente
PRAGMA main.temp_store = MEMORY;
.He creado bases de datos SQLite de hasta 3.5 GB de tamaño sin problemas de rendimiento notables. Si no recuerdo mal, creo que SQLite2 podría haber tenido algunos límites inferiores, pero no creo que SQLite3 tenga tales problemas.
Según la página de Límites de SQLite , el tamaño máximo de cada página de base de datos es de 32K. Y el máximo de páginas en una base de datos es 1024 ^ 3. Entonces, según mis cálculos, eso llega a 32 terabytes como el tamaño máximo. ¡Creo que alcanzarás los límites de tu sistema de archivos antes de llegar a los de SQLite!
fuente
Gran parte de la razón por la que tardó más de 48 horas en hacer sus inserciones se debe a sus índices. Es increíblemente más rápido:
1 - Descartar todos los índices 2 - Hacer todas las inserciones 3 - Crear índices nuevamente
fuente
Además de la recomendación habitual:
He aprendido lo siguiente de mi experiencia con SQLite3:
Altere la mesa más tarde según sea necesarioNo puede agregar restricciones con ALTER TABLE).Pregunta / comentario de bienvenida. ;-)
fuente
Creo que las principales quejas sobre el escalado de sqlite son:
fuente
Tengo una base de datos SQLite de 7GB. Para realizar una consulta particular con una unión interna se necesitan 2.6s. Para acelerar esto, intenté agregar índices. Dependiendo de qué índice (s) agregué, a veces la consulta bajó a 0.1s y a veces subió a 7s. Creo que el problema en mi caso fue que si una columna está muy duplicada, agregar un índice degrada el rendimiento :(
fuente
Solía haber una declaración en la documentación de SQLite de que el límite de tamaño práctico de un archivo de base de datos era unas pocas docenas de GB: s. Esto se debió principalmente a la necesidad de que SQLite "asigne un mapa de bits de páginas sucias" cada vez que inició una transacción. Por lo tanto, se requerían 256 bytes de RAM por cada MB en la base de datos. Insertar en un archivo DB de 50 GB requeriría un fuerte (2 ^ 8) * (2 ^ 10) = 2 ^ 18 = 256 MB de RAM.
Pero a partir de versiones recientes de SQLite, esto ya no es necesario. Lee más aquí .
fuente
2^18
en realidad solo son 256 K.He experimentado problemas con archivos sqlite grandes cuando uso el comando de vacío.
Todavía no he probado la función auto_vacuum. Si espera actualizar y eliminar datos a menudo, entonces vale la pena ver esto.
fuente