2014-06-27 7 views
7

Ten jeden jest związany z spatilite również (i nie tylko SQLite)UPDATE szybciej w SQLite + rozpocząć transakcji

Mam bazę danych plików (xyz.db), które używam przez SQLiteconnection (SQLiteconnection to rozciąga się spatialite).

Mam tak wiele rekordów musi zaktualizować do bazy danych.

   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; 
       } 

temperaturze powyżej logiką castarraylist jest Arraylist który zawiera wartości, które trzeba przetworzyć w bazie danych.

Kiedy sprawdziłem powyższy kod aktualizując około 400 rekordów w ciągu 1 minuty.

Czy istnieje sposób, w jaki mogę poprawić wydajność?

UWAGA :: (plik bazy danych nie jest bezpieczny wątku)

2. rozpocząć transakcji

Załóżmy Chciałbym uruchomić dwie (lub miliony) instrukcję aktualizacji z pojedynczej transakcji w Spatialite .. Czy to możliwe ?

czytam online i przygotować poniżej rachunku dla mnie (ale nie uzyskać sukces)

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; 

Powyższe stwierdzenie nie aktualizuje rekordy w mojej bazy danych. czy SQLite nie obsługuje BEGIN TRANSACTION? Czy jest coś, czego mi brakuje?

i jeśli trzeba uruchomić indywidualny oświadczenie to zabiera zbyt dużo czasu, aby aktualizować jak wspomniano powyżej ...

Odpowiedz

15

SQLite obsługi transakcji, można spróbować poniżej kodu.

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

jak ta logika jest inna niż powyżej? tak jak tutaj mamy również uruchomioną pętlę ** for ** i zapętla się ona do 1000 razy – Hardik

+0

możesz zobaczyć powyższe zapytanie zostanie wykonane dla wszystkich rekordów w castarraylist, po zakończeniu transakcji commit, możesz wypróbować powyższy kod i zobaczyć wynik. – Suresh

+0

Tak, poprawiono, ale nadal nie jest skuteczne. Dla 100000 rekordów trwa to> 50 minut. Tak więc ręcznie zebrałem czas na wykonanie każdej pęczki 5000 rekordów. Tam, gdzie zauważyłem, wzrasta czas, podczas gdy każdy pęczek. 5000 rekordy czas przetwarzania 1-te> 01:11 minute 2-ty> 1:25 minut 3-ty> 1:32 minut 4-te> 1:40 minut 5-ty> 1:47 minut 6-ty> 1:52 minut ... ... ... 17-ty> 3:32 minut 18-ty> 03:44 munite 19-ty> 4:02 minut 20-te> 4:56 minut dlaczego tak jest? potrzebujesz uruchomić jakieś inne polecenie zwiększania pamięci? – Hardik

5
  • Podstawowym celem transakcji bazy aby zrobić wszystko, albo nic jeśli coś się nie powiedzie wewnątrz;

  • Ponowne użycie tego samego SQLiteCommand obiektu poprzez zmianę jego CommandText własności i wykonać go ponownie i ponownie może być szybciej, ale prowadzi do napowietrznych pamięci: Jeśli masz ważną ilość zapytań do wykonywania, najlepiej aby pozbyć się przedmiotu po użyciu i utworzyć nowy;

Wspólny wzór dla transakcji ADO.NET jest:

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

Skąd wiadomo, że prowadzi do obciążenia pamięci? –

+0

Prywatne użycie pamięci w menedżerze zadań. Nie pojawia się, gdy poprawnie udostępniam SQLiteCommand. [To zachowanie było również widoczne tutaj] (http://stackoverflow.com/questions/5311897/how-can-i-recycle-my-sqlitecommand-to-speed-up-this-sqlite-bulk-insert-ios) . Również [tutaj] (http://stackoverflow.com/questions/15408207/do-i-have-to-dispose-the-sqlitecommand-objects). Nawiasem mówiąc, jestem zainteresowany, jeśli istnieje rozwiązanie tego problemu :) – Larry

Powiązane problemy