Как повысить эффективность соединений SQLite

Есть ли какое-либо преимущество в том, что локальное соединение sqlite открывается все время работы?

Обычно я создаю новое соединение, а затем закрываю его в каждом методе, который выполняет операцию с базой данных. Он будет выглядеть примерно так:

myMethod(Context context){
    LocalDBHelper localDBHelper = new LocalDBHelper(context); //extended SQLiteOpenHelper 
    SQLiteDatabase db = localDBHelper.getWritableDatabase();
    ...
    localDBHelper.close();
}

Итак, в типичной пользовательской сессии это произойдет примерно в 10 раз. Было бы целесообразно создать соединение в onResume(), использовать это во всех методах доступа к базе данных и, наконец, закрыть его в onPause()?

Ответ 1

Есть ли какое-либо преимущество в том, что локальное соединение sqlite открывается все время работы?

Обычно вам требуется одно "соединение" для всей жизни вашего процесса. В частности, вы не хотите, чтобы несколько "подключений" использовались одновременно в нескольких потоках. Вся логика безопасности потоков для SQLite в Android основана на использовании одного SQLiteDatabase (и, следовательно, одиночного SQLiteOpenHelper) для всех этих потоков, поэтому можно сделать правильную блокировку.

Ответ 2

Поскольку ваше приложение работает на одной и той же машине каждый раз, когда оно подсвечивается, и к нему обращается одна и та же память, поэтому нет проблем, чтобы он был открытым. потому что в том же пространстве памяти sqlite просто загружается, как DLL для основного приложения.

Только одна проблема может возникнуть! когда вы хотите запускать много потоков для одновременного доступа к базе данных (например, с помощью AsyncTask), интерференция между ними заставляет некоторые потоки останавливаться! поэтому лучше всего создавать соединения для новых потоков каждый раз!

Ответ 3

На основе ответа @CommonsWare я применил шаблон Singleton, чтобы иметь один экземпляр приложения LocalDBHelper с использованием ленивого экземпляра. Он работает до сих пор и избегает необходимости создавать экземпляр и закрывать помощник/базу данных для каждой операции.

public class MyApplication extends Application{
    private static MyApplication instance;
    public MyApplication(){
        instance = this;
    }
    public static Context getContext(){
        return instance;
    }
}

public class LocalDBHelper extends SQLiteOpenHelper{
    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME = "MyDB";
    private static final String LOG_TAG = "LocalDBHelper";

    private static LocalDBHelper instance = null;
    /*private constructor to avoid direct instantiation by other classes*/
    private LocalDBHelper(){
        super(MyApplication.getContext(), DATABASE_NAME, null, DATABASE_VERSION);
    }
    /*synchronized method to ensure only 1 instance of LocalDBHelper exists*/
    public static synchronized LocalDBHelper getInstance(){
        if(instance == null){
            instance = new LocalDBHelper();
        }
        return instance;
    }
    ...
    ...
}

Использование:

SQLiteDatabase db = LocalDBHelper.getInstance().getWritableDatabase();
db.insert(...)

Использование транзакций:

SQLiteDatabase db = LocalDBHelper.getInstance().getWritableDatabase();
db.beginTransaction();
try{
....
...
db.setTransactionSuccessful();
}catch(Exception e){
    e.printStackTrace();
}
finally{
    db.endTransaction();

}

Важно: нет необходимости звонить localDBHelper.getInstance().close() в любом месте

Ответ 4

Лично мне легче называть SQL-соединения, необходимые для начальной загрузки приложения, для хранения в SQLite DB и либо устанавливать кнопку обновления для пользователя, чтобы решить, когда они хотят обновить данные, либо установить периодическую интервал времени обновления для приложения.

Таким образом, вы повышаете производительность при общем использовании приложения, помещая нагрузку данных на предварительно определенное пользователем время.

Хотя я полагаю, это зависит от того, как часто будет выполняться взаимодействие с БД....

Этот вопрос может дать вам несколько полезных ответов:

Должен ли я постоянно открывать() и закрывать() мою базу данных SQL или оставлять ее открытой?