I have an SQLite database from which I need to delete records periodically. What is the best way, performance-wise, to do this. I have an array of unique PK ids. I’ve come up with 2 methods:
Using a prepared statement
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();
}
Or by using the ‘in’ keyword
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();
}
The ideal approach would be a combination of the two: a prepared statement of all IDs.
So, avoid SQL injection and use an approach like this (in pseudo-code):
Performance-wise, this might be better as the database will rebalance indexes after all deletes. Working in a transaction and committing once after all individual deletes would do essentially the same, though. The approach I propose is only safer.
As often discussed on SO, SQLite performance varies greatly on various criteria, namely the structure, number of rows, page size, etc. There is no universal “faster in all cases” approach with SQLite. Your mileage will vary.