public synchronized void updateStop(ArrayList<StopBean> beanList){
SQLiteDatabase db = getWritableDatabase();
String query = "DELETE FROM 'stop'";
db.execSQL(query);
for(StopBean bean : beanList){
String atco_code = bean.getAtco_code();
String name = bean.getName();
String locality = bean.getLocality();
String bearing = bean.getBearing();
String latitude = bean.getLatitude()+"";
String longitude = bean.getLongitude()+"";
ContentValues values = new ContentValues();
values.put("atco_code", atco_code);
values.put("name", name);
values.put("locality", locality);
values.put("bearing", bearing);
values.put("latitude", latitude);
values.put("longitude", longitude);
db.insert("stop", null, values);
}
db.close();
}
目前,我们的应用程序通过上述方法插入4,000行。这种方法的问题是实际执行需要10-15秒。显然,这对于简单的4,000行插入来说太长了。
如何更改此方法,以便大大加快这些插入的执行时间?
答案 0 :(得分:6)
使用beginTransaction()
,endTransaction()
和markTransactionAsSuccessful()
将整件事物包裹在一个交易中。现在,你每个插入一个事务,这意味着每个插入一个磁盘I / O脉冲,这将非常慢。
除此之外:
不要在循环的每次传递中分配新的ContentValues
摆脱局部变量(例如atco_code
),以防它们未被优化掉
使用更有效的方法将数字转换为字符串而不是&#34;&#34; (例如,Double.toString()
尝试将简单的SQL INSERT
语句编译为SQLiteStatement
via compileStatement()
,看看这是否比调用insert()
更好
如果您仍然不满意,请使用Traceview并确定剩余时间用于何处。
答案 1 :(得分:3)
在recent versions of sqlite(Kit Kat,Jelly Bean和Lollipop,according to the emulators)中,您可以使用多插入语句:
INSERT INTO table (col1, col2) VALUES
('row1col1', 'row1col2'), ('row2col1', 'row2col2');
如果您要导入静态可信数据,请将包含数据的sqlite脚本与您的应用一起包含在文件中,然后在首次启动时运行它。注意:永远不要将SQL值连接到SQL查询中,因为这会打开您的数据库注入(并且它不会更快,因为您和sqlite将解析数据两次并执行不必要的重新编译)。
如果需要插入动态生成的数据或者需要支持旧版本,则应使用预准备语句预编译SQL查询并使用绑定变量。例如:
db.beginTransaction();
String sql = "INSERT INTO stop(atco_code, name, locality, bearing, latitude, longitude) VALUES (?,?,?,?,?,?)";
SQLiteStatement stmt = db.compileStatement(sql);
for(StopBean stop : stopList){
stmt.bindString(1, stop.getAtco_code());
stmt.bindString(2, stop.getName());
stmt.bindString(3, stop.getLocality();
stmt.bindString(4, stop.getBearing());
stmt.bindDouble(5, stop.getLatitude());
stmt.bindDouble(6, stop.getLongitude());
stmt.execute();
stmt.clearBindings();
}
db.setTransactionSuccessful();
db.endTransaction();
在所有情况下,您应该将所有插入包装在单个事务中。使用单个事务允许数据库将值缓存在快速RAM中,并仅在缓存已满或完成时刷新数据,而不是将数据刷新到每个插入语句的持久存储。