我有一个SQLite数据库,我需要定期删除记录。这样做的最佳方式是性能方面。我有一系列独特的PK ID。我想出了两种方法:
使用准备好的声明
int[] ids = {1,2,3,4,5}; //example only, will be built elsewhere
Database db = null;
try {
db = DataConnection.getInstance(); //my class to get the connection instance
db.beginTransaction();
Statement st = db.createStatement("DELETE FROM myTable WHERE id = ?");
st.prepare();
for (int i=0;i<ids.length;i++) {
st.bind(1, ids[i]);
st.execute();
st.reset();
}
db.commitTransaction();
} catch (FileIOException e) {
e.printStackTrace();
} catch (DatabaseException e) {
e.printStackTrace();
}
或使用'in'关键字
int[] ids = {1,2,3,4,5}; //example only, will be built elsewhere
Database db = null;
try {
db = DataConnection.getInstance();
//Util.JoinArray(int[] ids,char delim, char prepend, char postpend) returns a String of the ids separated by delim with prepend at the front and postpend at the end
Statement st = db.createStatement("DELETE FROM myTable WHERE id IN " + Util.joinArray(ids,',','(',')'));
st.prepare();
} catch (FileIOException e) {
e.printStackTrace();
} catch (DatabaseException e) {
e.printStackTrace();
}
答案 0 :(得分:4)
理想的方法是将两者结合起来:准备好所有身份证明。
因此,避免SQL注入并使用这样的方法(伪代码):
query = "DELETE FROM myTable WHERE id IN (";
for (int i = 0; i < ids.count; i++)
query.Append("?,");
query.DropLast(); //Remove the last comma
query.Append(")");
st = db.createStatement(query);
st.prepare();
for (int i = 0; i < ids.count; i++)
st.bind(i+1, ids[i]);
性能方面,这个可能更好,因为数据库将在所有删除后重新平衡索引。但是,在一个事务中工作并在所有单个删除之后提交一次将基本上相同。我建议的方法只是更安全。
正如在SO上经常讨论的那样,SQLite的性能在各种标准上有很大差异,即结构,行数,页面大小等。使用SQLite没有通用的“在所有情况下都更快”的方法。你的里程会有所不同。