Первый раз Курсор работает так медленно, когда запрашивает объемные данные. Как решить?
Я должен запросить три таблицы и отобразить данные для моего customerView.
Мой код такой:
Log.v(TAG, System.CurrentTimeMillis())
int len = cursor.getCount();
Log.v(TAG, System.CurrentTimeMillis())
Product[] products = new Product[len];
int i = 0;
while(cursor.moveToNext()){
products[i] = new Product(cursor.getstring(0),.....);
}
Log.v(TAG, System.CurrentTimeMillis())
Sqlite запрос:
String sql = "SELECT T1.PRODUCT_ID, CODE, SHORT_DESCRIPTION, CATEGORY_CODE,
BRAND_CODE, FORM_CODE, DENOMINATOR, T1.PIECE_PRICE, T1.lowest_piece_price,
T2.sku_type, T1.master_sku " +
"FROM CUSTOMER_PROD_LIST_ITEMS T1 INNER JOIN PRODUCT T2 ON
T1.PRODUCT_ID = T2.ID INNER JOIN PRODUCT_UOMS ON T2.ID =
PRODUCT_UOMS.PRODUCT_ID"+
"WHERE T1.VALID = 1 AND PRODUCT_UOMS.VALID = 1 AND
CUSTOMER_PRODUCT_LIST_ID = " + customer_pdtlist_ID + "
ORDER BY T1.PRODUCT_ID ASC";
После моего тестирования, если у нас есть 1500 строк в курсоре, нам нужно потратить более 30 секунд, чтобы закончить эту строку (cursor.getcount()) . Если я удаляю эту строку, и использую ArrayList, чтобы иметь место. я могу найти, что мы должны потратить более 30 секунд на Cursor.moveToNext().
Поэтому мой вопрос: почему первая операция с курсором должна занимать так много времени? и как мы решаем?
И у этого человека такой же вопрос Плохая реализация SQLite? Первый раз доступ к данным слишком медленный. но ответ не работает для меня. Кстати, я нахожу дисплей те же 1500rows в Iphone, просто нужно amost 3s.
заранее спасибо!!
2 ответа
Хорошо, ребята, я не был здесь несколько дней. И я нашел решение, которое заключается в том, что вы должны создать индекс для своей таблицы, который улучшит скорость запроса. все равно спасибо
Это ответ на вопрос, почему первая операция на вашем курсоре такая медленная. Когда курсор поддерживается SQLite, Android использует библиотеку sqlite C для внутреннего использования и создает Cursor
аналогично созданию подготовленного оператора в библиотеке C. Создание подготовленного оператора обходится дешево и не выполняет никаких запросов. Взято из документации библиотеки C:
sqlite3_prepare()
Эта подпрограмма преобразует текст SQL в подготовленный объект оператора и возвращает указатель на этот объект. Для этого интерфейса требуется указатель соединения с базой данных, созданный предыдущим вызовом sqlite3_open(), и текстовая строка, содержащая инструкцию SQL, которая будет подготовлена. Этот API фактически не оценивает оператор SQL.Он просто подготавливает инструкцию SQL для оценки.
Когда вы звоните moveToNext()
наCursor
вот тогда запрос действительно выполняется.moveToNext
приводит к вызовуsqlite3_step()
функция в библиотеке C. Опять же, взяты из документации:
sqlite3_step()
Эта подпрограмма используется для оценки подготовленного оператора, который был ранее создан интерфейсом sqlite3_prepare(). Оператор оценивается до точки, в которой доступен первый ряд результатов. Чтобы перейти ко второму ряду результатов, снова вызовите sqlite3_step(). Продолжайте вызывать sqlite3_step(), пока инструкция не будет завершена. Операторы, которые не возвращают результаты (например, операторы INSERT, UPDATE или DELETE), выполняются до завершения при одном вызове sqlite3_step().
Поэтому создание курсора выполняется лениво, а запрос оценивается только при первом перемещении курсора.
Чтобы узнать, почему запрос занимает так много времени, используйтеEXPLAIN QUERY PLAN
по вашему запросу и посмотрите, где находится узкое место. Обычно это отсутствие соответствующего индекса.