SQLite – 在Android应用中加速4,000行插入
public synchronized void updateStop(ArrayList 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行插入来说太长了。
如何更改此方法以便大大加快这些插入的执行时间?
使用beginTransaction()
, endTransaction()
和markTransactionAsSuccessful()
将整个事物包装在事务中。 现在,您每个插入执行一次事务,这意味着每个插入一个磁盘I / O脉冲,这将非常慢。
除此之外:
-
不要在循环的每次传递中分配新的
ContentValues
-
摆脱局部变量(例如,
atco_code
),以防它们没有被优化掉 -
使用更有效的方法将数字转换为字符串而不是“”(例如,
Double.toString()
-
尝试通过
compileStatement()
编译一个简单的SQLINSERT
语句到SQLiteStatement
,看看是否比调用insert()
更好
如果您仍然不满意,请使用Traceview并确定剩余时间用于何处。
在最新版本的sqlite ( 根据模拟器 ,Kit Kat,Jelly Bean和Lollipop)中,您可以使用多插入语句:
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中,并仅在缓存已满或完成时刷新数据,而不是将数据刷新到每个插入语句的持久存储。
- 将应用程序从Eclipse移植到Android Studio时出错
- 阿卡。 Android系统。 NoSuchMethodException:
- 在尝试将大型json数据发送到android中的服务器时出现OutOfMemoryException?
- VideoView Streaming:音频有效但video为黑色
- Button.findViewById()上的NullPointerException
- Android Camera.takePicture失败了
- 在API 21上可以使用finishAndRemoveTask()
- 谷歌地图Android缩放到国家
- 如何解决java.lang.string无法使用xml解析器强制转换为java.lang.integer android