Плохая реализация SQLite? Первый раз доступ к данным слишком медленный
Я новичок в программировании для Android, но я довольно привык работать с базами данных SQLite.
Мое приложение открывает базу данных SQLite3 на SD-карте и выполняет относительно сложный запрос (5 объединений, 1 подзапрос, 2 предложения где), используя
SQLiteDatabase.rawQuery
public Cursor queryDataBase(String sql, String[] selectionArgs){ Cursor c = myDB.rawQuery(sql, selectionArgs); return c; }
Оператор SQL задается жестко
String
,- Запрос возвращает 585 строк с 24 столбцами.
- Мне пришлось сделать компромисс между пространством хранения и индексированием, но для всех больших таблиц (на данный момент около 40 000 записей) используются индексы, SQLite показывает для запроса:
Steps: 155 , Sorts: 0, AutoIdx: 1077
Я не использую первичные ключи, поэтому я также не переименовал ничего в "_id".
Выполнение rawQuery относительно быстрое, время выполнения составляет около 2 мс.
- Доступ к этим данным занимает слишком много времени, например, с помощью c.moveToFirst(), время выполнения составляет около 1700 мс! (то же самое для Cursor.getRowCount() или, по-видимому, для всех, кто впервые обращается к фактическому набору результатов).
- Выполнение этого на ПК (2 ГГц, 1 ГБ ОЗУ, жесткий диск SATA2) с использованием, например, SQLiteSpy, для отображения набора результатов занимает 15 мс.
- Выполнение этого на ПК с реализацией C++ также занимает от 15 мс до 30 мс.
Так чего мне здесь не хватает? Возможно ли, что мой телефон с 800 МГц, 2 ГБ оперативной памяти, MicroSD примерно в 120 раз медленнее?
2 ответа
Выполнение rawQuery относительно быстрое, время выполнения составляет около 2 мс.
Доступ к этим данным занимает слишком много времени, например, с помощью c.moveToFirst(), время выполнения составляет около 1700 мс! (то же самое для Cursor.getRowCount() или, по-видимому, для всех, кто впервые обращается к фактическому набору результатов).
Это ключевой момент: rawQuery на самом деле не выполняет запрос, но это задерживается до тех пор, пока в первый раз не понадобятся результаты запроса.
Помимо того, что он все еще немного медленнее, чем на ПК, проблема, похоже, заключается в обработке неиндексированных полей.
Хотя конфигурация в моем исходном посте была примерно в 120 раз медленнее, я пытался сделать то же самое с полной индексированной базой данных (это означает, что индексирует и первичные ключи везде, где это необходимо), и запрос, который теперь занимает 9 мс на ПК, теперь "только" 8 в разы медленнее: время выполнения около 75 мс.
Это, конечно, все еще довольно разочарованный результат, потому что я не хочу использовать индексы каждый раз, даже на очень маленьких таблицах.