2013-06-28 20 views
7

Muszę dodać ogromne dane w bazie danych SQLite i potrzebuję sugestii, jak mogę to zrobić w iOS. Muszę zsynchronizować około 1   GB danych z serwera do bazy danych SQLite iPhone'a.Przechowywanie ogromnych danych w SQLite

Potrzebuję alternatywnych sposobów przechowywania szybkich danych w bazie danych po stronie iOS. Próbowałem przechowywać dane jeden po drugim, ale zabiera to zbyt dużo czasu na synchronizację i przechowywanie danych.

+0

użyć SQLTransaction do wstawienia danych do tabeli – Kalpesh

+0

Czy 1 GB dotyczy tylko początkowej synchronizacji, czy cyklicznej? –

+3

Jeśli kilka rekordów, transakcji może pomóc. Jeśli masz duże bloki, SQLite nie nadaje się do tego. Powiedz nam więcej o danych, być może udostępniając jakiś kod źródłowy. Przy okazji, wydaje mi się, że czynnikiem ograniczającym będzie pobieranie go z serwera, a nie zapisywanie go na urządzeniu. – Rob

Odpowiedz

4

Proponuję zapoznać się z przepełnieniem stosu pytanie:

How do I improve the performance of SQLite?

To bardzo thourough spojrzenie na sposób poprawić wydajność SQLite w ogóle, i to było bardzo pomocne, gdy byłem uderzenie problemy prędkości próbuje wstawić 100 000 rekordów do bazy danych SQLite na iOS.

W szczególności wykorzystanie transakcji dramatycznie zmniejsza ogólną szybkość wstawiania. Oto krótki fragment kodu, dzięki czemu można zobaczyć, co mam na myśli:

const char *dbpath = [[Utilities pathInDocumentsFolder: MY_DATABASE] UTF8String]; 
const char *sql = "INSERT INTO Filters (Region, District, Territory) " \ 
    "VALUES (?, ?, ?)"; 
sqlite3 *mapDB; 
char *sqliteError; 

sqlite3_stmt *insertStatement; 

sqlite3_open(dbpath, &mapDB); 

sqlite3_exec(mapDB, "BEGIN TRANSACTION", NULL, NULL, &sqliteError); 

if (sqlite3_prepare_v2(mapDB, sql, -1, &insertStatement, NULL) == SQLITE_OK) { 
    for (NSArray *row in filtersArray) { 
     sqlite3_bind_text(insertStatement, 1, [[row objectAtIndex: 0] UTF8String], -1, SQLITE_TRANSIENT); // Region 
     sqlite3_bind_text(insertStatement, 2, [[row objectAtIndex: 1] UTF8String], -1, SQLITE_TRANSIENT); // District 
     sqlite3_bind_text(insertStatement, 3, [[row objectAtIndex: 2] UTF8String], -1, SQLITE_TRANSIENT); // Territory 

     if (sqlite3_step(insertStatement) != SQLITE_DONE) { 
      break; 
     } 

     sqlite3_clear_bindings(insertStatement); 
     sqlite3_reset(insertStatement); 
    } 
} 

sqlite3_exec(mapDB, "END TRANSACTION", NULL, NULL, &sqliteError); 

sqlite3_finalize(insertStatement); 

sqlite3_exec ze sprawozdaniem BEGIN i END TRANSACTION są magiczne.

+0

+1 Uzgodniono. Podczas wstawiania wielu rekordów wykorzystanie transakcji poprawia wydajność o kilka rzędów wielkości. Również ponowne wiązanie pomaga, ale przyrost wydajności jest skromniejszy. – Rob

+1

Mogę również zaproponować logowanie 'sqlite3_errmsg (mapDB)' jeśli nie otrzymasz 'SQLITE_OK' jako kodu powrotu z różnych wywołań funkcji' sqlite3' (lub 'sqlite3_step', kod powrotu' SQLITE_DONE'). – Rob

+1

I, BTW, masz dodatkowy symbol "?" W twoim SQL. To tylko przykład, więc to nie jest wielka sprawa, ale tylko FYI. Nie musisz również "\", aby kontynuować ciąg znaków w następnym wierszu kodu. Potrzebujesz tylko odwrotnego ukośnika, jeśli nie masz zamykającego cudzysłowu na końcu pierwszej linii i nowego cudzysłowu otwierającego na początku następnego. Sposób w jaki go masz, backslash jest niepotrzebny. – Rob

Powiązane problemy