without with primary index foreign create autoincrement sqlite indexing insert primary-key

with - sqlite primary key autoincrement



Sqlite3: ¿Desactivar el índice de clave principal durante la inserción? (3)

Tengo una base de datos Sqlite3 con una tabla y una clave principal que consta de dos enteros, y estoy tratando de insertar muchos datos en ella (es decir, alrededor de 1GB o menos)

El problema que estoy teniendo es que la creación de la clave principal también crea implícitamente un índice, que en mi caso se enloda y se inserta en un rastreo después de algunas confirmaciones (y eso sería porque el archivo de la base de datos está en NFS .. suspiro ).

Por lo tanto, me gustaría de alguna manera desactivar temporalmente ese índice. Hasta ahora, mi mejor plan consistía en eliminar el índice automático de la clave principal, pero parece que a SQLite no le gusta y arroja un error si intento hacerlo.

Mi segundo mejor plan implicaría que la aplicación realizara copias transparentes de la base de datos en la unidad de red, haciendo modificaciones y luego fusionándola. Tenga en cuenta que a diferencia de la mayoría de las preguntas SQlite / NFS, no necesito concurrencia de acceso.

¿Cuál sería la forma correcta de hacer algo como eso?

ACTUALIZAR:

Olvidé especificar las banderas que ya estoy usando:

PRAGMA synchronous = OFF PRAGMA journal_mode = OFF PRAGMA locking_mode = EXCLUSIVE PRAGMA temp_store = MEMORY

ACTUALIZACIÓN 2: De hecho, estoy insertando elementos en lotes, sin embargo, cada lote siguiente es más lento de comprometer que el anterior (supongo que esto tiene que ver con el tamaño del índice). Intenté hacer lotes de entre 10k y 50k tuplas, cada uno de los cuales constaba de dos enteros y un flotador.


¿Está haciendo el INSERT de cada nuevo como una transacción individual?

Si usa BEGIN TRANSACTION e INSERT filas en lotes, entonces creo que el índice solo se reconstruirá al final de cada transacción.


  1. No puede eliminar el índice incrustado ya que es la única dirección de la fila.
  2. Fusiona tus 2 claves enteras en una sola tecla larga = (tecla1 << 32) + tecla2; y haga esto como INTEGER PRIMARY KEY en su esquema youd (en ese caso tendrá solo 1 índice)
  3. Establezca el tamaño de página para la nueva base de datos al menos 4096
  4. Eliminar CUALQUIER índice adicional, excepto primario
  5. Complete los datos en el orden CLASIFICADO para que la clave primaria esté creciendo.
  6. Reutilice los comandos, no los cree cada vez desde una cadena
  7. Establezca el tamaño de la memoria caché de página en la cantidad de memoria que le quede (recuerde que el tamaño de la memoria caché está en el número de páginas, pero no en el número de bytes)
  8. Cometa cada 50000 artículos.
  9. Si tiene índices adicionales, créelos solo DESPUÉS DE QUE TODOS los datos estén en la tabla

Si puedes fusionar la clave (creo que estás utilizando 32 bits, mientras que sqlite usa 64 bits, así que es posible) y rellenar los datos en orden ordenado, apostarás a que llenarás tu primer Gb con el mismo rendimiento que el segundo y ambos será lo suficientemente rápido