Robitex's Blog

Ideas in the web

Se SQLite vi sembra lento…


Sommario

Indagine sul perché SQLite fosse così lento ad inserire i dati…
In un progetto di elaborazione dati ho utilizzato un database SQLite per gestire un set di dati abbastanza complesso. Fino ad ora ammettevo che il codice per l’inserimento dei dati fosse molto lento contrariamente all’esecuzione delle query…

Cosa ho vantaggiosamente scoperto

L’inserimento dei dati avviene in SQLite all’interno di transazioni che hanno lo scopo di salvare i dati in modo sicuro. Se eseguo un inserimento tramite la normalissima funzione SQL INSERT, SQLite attende che ogni record inserito sia completamente e con successo salvato fisicamente sul disco.
Questo comportamento è dovuto al fatto che l’istruzione viene inserita automaticamente in una transazione.

Il numero di transazioni che SQLite è in grado di completare è dell’ordine di 10 al secondo, ed ecco spiegato il motivo di quelle strane attese. All’interno di una transazione invece il numero di inserimenti è dell’ordine di 50.000 al secondo.

Soluzioni

Compreso che ogni inserimento crea implicitamente una transazione, le alternative sono due:

  1. non fare niente e lasciare che i dati vengano inseriti con una transazione alla volta per usufruire della massima affidabilità;
  2. rendere le operazioni molto più veloci operando all’interno di un’unica transazione, ma anche meno sicure in caso di guai con il processo client.

…naturalmente ho preferito la seconda…

Giusto per fissare le idee

Giusto per fissare le idee, il codice che ho utilizzato, scritto in Lua e che utilizza la libreria LJSQLite3 scritta per luajit, è il seguente:

-- carico la libreria LJSQLite3
local sql = require "ljsqlite3"

-- creo la connessione
-- (in dbfilename è salvato il nome effettivo del file)
    local conn = sql.open( dbfilename, "rw")

-- abilito il vincolo di chiave esterna
-- per il momento non ON di default per mantenere
-- compatibilità con versione precedenti di SQLite3 versione 3.6
    conn:exec("PRAGMA foreign_keys = ON;")

-- creo una transazione
    conn:exec "BEGIN" -- begin transaction

-- codice per inserire i dati nel database
-- per esempio con un prepared statement
-- (codice esemplificativo con nomi tabella e campi per riferimento)
   local stmt = conn:prepare("INSERT INTO mytable " ..
     .. "(field_1, field_2, ..., field_n)" ..
     .. " VALUES (?, ?, ..., ?);" )
...
...
... eccetera eccetera

-- chiudo la transazione
    conn:exec "END"

-- chiudo la connessione
    conn:close()

Saluti e buona estate.

Una risposta a “Se SQLite vi sembra lento…

  1. Pingback:Visto nel Web – 79 | Ok, panico

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

%d blogger cliccano Mi Piace per questo: