2013-03-08 9 views
12

Spędzałem sporo czasu, przeglądając niektóre problemy z wydajnością na naszym urządzeniu, i zauważyłem, że mamy sporo aplikacji, które wykonują db czyta/pisze ..Dlaczego program InsertHelper był przestarzały?

Zacząłem od użycia interfejsu API Kontaktów w celu wstawienia nowych kontaktów & wierszy danych, i to było boleśnie powolne. 1 minuta 18 sekund na wstawienie około 1500 wierszy (250 nieprzetworzonych kontaktów & 1250 wierszy danych) ..

Użyłem pomocnika wstawki w innej aplikacji dla wkładek wydajności i zdecydowałem się napisać testową aplikację, która zapisywałaby do oddzielnych baz danych w/oddzielne metody wstawiania.

Każda db ma jedną tabelę, każda w/4 kolumny: _ID, Nazwa, Czas i Blob (wszystkie typu "ciąg") - tak jak dostawca danych określa kolumny danych.

_ID to auto increment pk, nazwa po prostu wstawia to samo "1234567890", czas jest tylko bieżącym czasem systemowym w milis, a BLOB jest ciągiem o długości 6400 pełnej litery "A" ...

raz pierwszy sprawdził luzem insert, ale robi to pętle poprzez wszystkie wkładki zostały zdefiniowane, a jest tak wolna, jak robi wkładki indywidualnie (lub znikomy wpływ na wydajność) ..

testowałem 3 różne metody wprowadzania insertów: ContentValues ​​w/db.insert metoda: SQLiteStatement w/statement.execute() (wykonane wewnątrz transakcji). SqliteInsertHelper w/transakcji.

mogę dostarczyć jakiś kod, ale mam najlepszą wydajność wyjścia z InsertHelper, i zastanawiasz się, dlaczego to przestarzałe:

Czas wstawić 100 rekordów ContentValues: 7.778 sekund (82 bajtów napisany/MS) SQLiteStatement: 1.311 sekund (489 bajtów zapisanych/ms) SqliteInsertHElper: 0,292 sekundy (2197 bajtów zapisanych/ms)

Jakieś pomysły?

+0

zrobiłem kilka dodatkowych badań, a nie regularny wkładkę, ale sprawiły, że część transakcji, to znacznie poprawiło wydajność. Wygląda na to, że prawdopodobnie potrzebny jest jakiś kod (patrząc na dostawcę kontaktów). – Chrispix

+0

Biorąc pod uwagę problem wydajności, o którym wspomniałeś, transakcje byłyby moją pierwszą sugestią (każda transakcja wymaga czekania w obie strony, każda wstawka poza transakcją jest domyślnie zapakowana w jedną). Po tym może być pomocne czytanie: http://stackoverflow.com/questions/14344172/android-bulk-insert-when-inserthelper-is-deprecated – rutter

+0

Chciałbym zasugerować również transakcje. Wkładki, które testowałem przy transakcjach, były dość szybkie. – Luis

Odpowiedz

0

Aplikacja InsertHelper umożliwia użytkownikom tworzenie wielu wstawek do tabeli przy użyciu tej samej instrukcji. Jednak nie jest to dobry sposób wstawiania jako taki, ponieważ jest to not thread-safe.

+3

zgodnie z http://developer.android.com/reference/android/database/sqlite/SQLiteStatement.html, alternatywna rekomendacja nie jest bezpieczna dla wątków ani –

0

Powinieneś użyć transactions.. Jeśli nie tworzysz jawnie transakcji dla operacji bazy danych, framework tworzy po jednym dla każdego. Zgrupuj obiekt i wstaw wszystkie naraz. To znacznie zwiększy wydajność.

4

Trudno znaleźć jakiekolwiek informacje na temat powodów, dla których narzędzie InsertHelper było nieaktualne, bez przechodzenia do faktycznego zatwierdzenia, które powoduje jego odrzucenie. Inżynier, który wycofał narzędzie InsertHelper, podał następującą przyczynę:

Ta klasa nie ma żadnych zalet w stosunku do SQLiteStatement i sprawia, że ​​kod jest bardziej złożony i podatny na błędy.

Po refaktoryzacji z InsertHelper do SQLiteStatement zgadzam się. Jednym wyjątkiem są funkcje wiążące o zerowym bezpieczeństwie. Podczas gdy InsertHelper automatycznie wywołuje dla ciebie funkcję bindNull(), SQLiteStatement ulega awarii, jeśli przełączysz na przykład łańcuch zerowy i musisz wykonać własne zerowe sprawdzanie przed wywołaniem metody bindString().

Patrz: https://android.googlesource.com/platform/frameworks/base/+/b33eb4e%5E!/

+0

Rewizja dotycząca przechodzenia do dziennika zatwierdzeń w celu uzyskania autorytatywnej odpowiedzi. Dałbym ci więcej, gdybym mógł. – Dalbergia

Powiązane problemy