DB插入需要很长时间

时间:2013-01-30 07:49:51

标签: android sqlite

我使用以下代码将数据插入表格。

public CourseDB addcourseByType(CourseDB rmdb) {
        SQLiteDatabase db = this.getWritableDatabase();
        db.beginTransaction();
        try {
            ContentValues values = new ContentValues();
            values.put(COURSE_NAME, rmdb.getcourse_name()); 
            values.put(CATEGORY_COURSE_TYPE, rmdb.getcategory_course_type()); 
            values.put(COURSE_CRS, rmdb.getcourse_crs());
            values.put(CATEGORY_ID_FOR, rmdb.getcat_foreign_id()); // Contact
            db.insert(TABLE_COURSE, null, values);

            String selectQuery = "SELECT " + COURSE_ID + " FROM "
                + TABLE_COURSE + " WHERE " + COURSE_CRS + "='"
                + rmdb.getcourse_crs() + "'" + " AND " + CATEGORY_ID_FOR
                + "='" + rmdb.getcat_foreign_id() + "'";
            SQLiteDatabase db1 = this.getWritableDatabase();
            Cursor cursor = db1.rawQuery(selectQuery, null);
            // looping through all rows and adding to list
            if (cursor.moveToFirst()) {
                do {
                     rmdb.setcourse_id(Integer.parseInt(cursor.getString(0)));
                } while (cursor.moveToNext());
            }
            cursor.close();

        db.setTransactionSuccessful();
        } finally {
            db.endTransaction();
          }
       db.close();
       return rmdb;
}

请告诉我是否有任何方法可以更改代码以更快地添加值,我从文件中获取JSON格式的数据,将其存储为数组并将其传递给以上方法。

Asmita

我尝试了这些建议,并且能够将插入时间从16秒减少到11秒。请看一下我的新代码。是否有可能进一步减少它。

// //convert string to JSONArray
                JSONArray jArray = new JSONArray(bufferString);
                if (bufferString.isEmpty()) {


                } else {



                    db.deleteAllCourseByTypeDB(type);
                }


                boolean eventFlag = false;
                db.beginTransaction();
                SQLiteDatabase sqlDB = db.getWritableDatabase();

                 long startTime = System.currentTimeMillis();
                 ContentValues values = new ContentValues();
                for (int j = 0; j < jArray.length(); j++) {
            long insideStart = System.currentTimeMillis();

            JSONObject json_data = jArray.getJSONObject(j);
            String crsCd = (json_data.getString("crsCd"));
            String crsTitle = (json_data.getString("crsTitle"));
        System.out.println("Time for one JSON parsing "+(System.currentTimeMillis()-insideStart));

            try
                {

                    values.put(COURSE_NAME, crsTitle);                          values.put(CATEGORY_COURSE_TYPE, type); // Contact
                                                                                            // Name
                        values.put(COURSE_CRS, crsCd);
                        values.put(CATEGORY_ID_FOR, id_notebook2); // Contact
                        sqlDB.insert(TABLE_COURSE, null, values);
                        //Error in between database transaction 


                    }
                      finally {

                      }
                    System.out.println("Time for one One Looping "+(System.currentTimeMillis()-insideStart));

                }

                db.setTransactionSuccessful();
                db.endTransaction();
                db.close();
                long endTime = System.currentTimeMillis();
            System.out.println("this is my timer "+(endTime-startTime)/1000);


    } catch (FileNotFoundException e) { } catch (IOException e) {
        e.printStackTrace();

    } catch (JSONException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

4 个答案:

答案 0 :(得分:3)

您在同一方法单独的方法中将插入和选择查询分为两个用于插入和一个用于选择和尝试。 希望它有所帮助。

修改

很长一段时间后找到了一个解决方案

它工作得很快.....

String sql = "INSERT INTO table (column1, column2) VALUES (?, ?)";
db.beginTransaction();

SQLiteStatement stmt = db.compileStatement(sql);

for (int i = 0; i < values.size(); i++) {
    stmt.bindString(1, values.get(i).column1);
    stmt.bindString(2, values.get(i).column2);
    stmt.execute();
    stmt.clearBindings();
}

db.setTransactionSuccessful();
db.endTransaction();

对于10,000个数据,它只需要60秒。

答案 1 :(得分:0)

如果您了解操作类型,为什么要运行rawquery。 您可以使用API​​中指定的updateinsertselect方法来更改查询。

此外,如果你只能想到一个游标结果,那么你可能不需要循环。只需移动到第一个位置并获取值。

答案 2 :(得分:0)

首先,您不需要在同一函数中使用数据库类的第二个实例:SQLiteDatabase db = this.getWritableDatabase();而不是SQLiteDatabase db1 = this.getWritableDatabase();。仅使用db。其次,因为我可以看到您的列表将int作为参数,因此rmdb.setcourse_id(Integer.parseInt(cursor.getString(0)));可以更改为cursor.getInt();。无需额外转换。

最后关于插入,实现快速插入大部分数据的最佳方法是使用类似的东西:

String insertSql = "REPLACE INTO requested_cards ";
for (int j = 0; j < requested_cards.length(); j++) {
  int id = 0;
  try {
    id = requested_cards.getInt(j);
  } catch (JSONException e) {
    e.printStackTrace();
  }
  if (j == 0) {
    insertSql += "SELECT " + my_id
            + " AS id, " + id
            + " AS cardId ";
  } else {
    insertSql += "UNION SELECT " + my_id
            + " , " + id + " ";
  }


 }
 dbHelper.executeSQL(insertSql);

编辑:

所以你的陈述应该是这样的:

REPLACE INTO myTable 
SELECT myValueFromJSOn AS id, myAnotherValueFromJson AS name (and etc. depending on which rows you want to insert/update) 
UNION SELECT myValueFromJSON , myAnotherValueFromJSON
UNION SELECT myValueFromJSON, myAnotherValueFromJSON...

就是这样。

答案 3 :(得分:0)

如果您的主键是INTEGER AUTOINCREMENT,那么您的键是行ID的别名,而行ID正是由db.insert重新调整的。见here。因此,您无需为获取ID进行选择。