2014-06-27 10 views
7

Questo è legato alla spatilite anche (non solo SQLite)UPDATE più velocemente in SQLite + BEGIN TRANSACTION

Ho un database file di (xyz.db), che sto usando da SQLiteconnection (SQLiteconnection è si estende a SpatiaLite).

Ho così tanti record da aggiornare nel database.

   for (int y = 0; y < castarraylist.Count; y++) 
       { 
        string s = Convert.ToString(castarraylist[y]); 

        string[] h = s.Split(':'); 

        SQLiteCommand sqlqctSQL4 = new SQLiteCommand("UPDATE temp2 SET GEOM = " + h[0] + "WHERE " + dtsqlquery2.Columns[0] + "=" + h[1] + "", con); 
        sqlqctSQL4.ExecuteNonQuery(); 

        x = x + 1; 
       } 

Al di sopra logica castarraylist è Arraylist che contiene il valore che devono elaborare nel database.

Quando ho controllato il codice di cui sopra aggiornando circa 400 record in 1 minuto.

Esiste un modo per migliorare le prestazioni?

NOTA :: (base di dati del file non è thread-safe)

2. iniziare la transazione

Supponiamo Mi piace correre due (o milioni) dichiarazione di aggiornamento con un'unica transazione in SpatiaLite .. È possibile ?

ho letto on-line e si preparano al di sotto dichiarazione per me (ma non ottiene il successo)

BEGIN TRANSACTION; 
UPDATE builtuparea_luxbel SET ADMIN_LEVEL = 6 where PK_UID = 2; 
UPDATE builtuparea_luxbel SET ADMIN_LEVEL = 6 where PK_UID = 3; 
COMMIT TRANSACTION; 

Sopra dichiarazione non aggiornamento dei record nel mio database. SQLite non supporta BEGIN TRANSACTION? c'è qualcosa che mi manca?

e se ho bisogno di correre dichiarazione individuale, allora si sta prendendo troppo tempo per aggiornare come detto sopra ...

risposta

15

SQLite supporto delle transazioni, si può provare a seguito di codice.

using (var cmd = new SQLiteCommand(conn)) 
using (var transaction = conn.BeginTransaction()) 
{ 
    for (int y = 0; y < castarraylist.Count; y++) 
    { 
     //Add your query here. 
     cmd.CommandText = "INSERT INTO TABLE (Field1,Field2) VALUES ('A', 'B');"; 
     cmd.ExecuteNonQuery(); 
    } 
    transaction.Commit(); 
} 
+0

come questa logica è differisce poi di cui sopra? come qui stiamo anche eseguendo ** per ** loop ed è in loop per 1000 volte – Hardik

+0

puoi vedere sopra la query verrà eseguita per tutti i record in castarraylist, dopo che la transazione di completamento si impegnerà, puoi provare sopra il codice e vedere il risultato. – Suresh

+0

sì è migliorato ma non è ancora efficace. Per 100000 record che richiede> 50 minuti. Quindi ho raccolto manualmente il tempo per l'esecuzione di ogni gruppo di 5000 record. Dove ho notato che sta aumentando il tempo durante ogni gruppo. 5000 record di tempo di elaborazione prime> 01:11 minuti secondo> 01:25 minuti 3> 01:32 minuti 4> 01:40 minuti 5 °> 01:47 minuti 6> 01:52 minuti ... ... ... 17> 03:32 minuti 18> 03:44 munite 19> 04:02 minuti 20> 04:56 minuti perché è così? è necessario eseguire qualche altro comando di incremento della memoria? – Hardik

5
  • L'obiettivo primario di una transazione di database per fare tutto, o niente se qualcosa non funziona all'interno;

  • riutilizzare lo stesso oggetto SQLiteCommand cambiando la sua proprietà CommandText ed eseguirlo ancora e ancora potrebbe essere più veloce, ma porta ad un sovraccarico della memoria: Se si dispone di una quantità importante di query per eseguire, il meglio è disporre l'oggetto dopo l'uso e crearne uno nuovo;

un modello comune per una transazione ADO.NET è:

using (var tra = cn.BeginTransaction()) 
{ 
    try 
    { 
     foreach(var myQuery in myQueries) 
     { 
      using (var cd = new SQLiteCommand(myQuery, cn, tra)) 
      { 
       cd.ExecuteNonQuery(); 
      } 
     } 

     tra.Commit(); 
    } 
    catch(Exception ex) 
    { 
     tra.Rollback(); 
     Console.Error.Writeline("I did nothing, because something wrong happened: {0}", ex); 
     throw; 
    } 
} 
+0

Come sai che porta a un sovraccarico di memoria? –

+0

L'utilizzo della memoria privata nel task manager. Non si verifica quando dispongo correttamente SQLiteCommand. [Questo comportamento è stato anche visto qui] (http://stackoverflow.com/questions/5311897/how-can-i-recycle-my-sqlitecommand-to-speed-up-this-sqlite-bulk-insert-ios) . Anche [qui] (http://stackoverflow.com/questions/15408207/do-i-have-to-dispose-the-sqlitecommand-objects). A proposito, sono interrotto se c'è una soluzione a questo :) – Larry