当在字典查询应用程序中生成大量结果时,我似乎在某个时刻卡在每个插入500-1000毫秒。是否有任何我不理解的插入技巧或窍门?
以下是插入的示例
long id = this.getDbAdapter().insertData(
"combo",
result.getWord(),
String.valueOf(result.getNumLetters()),
String.valueOf(result.getPointsScrabble()),
String.valueOf(result.getPointsWordsWithFriends())
);
if (id < 0) {
Log.i(TAG, "Database combo insertion of " + result.getWord() + " unsuccessful :(");
} else {
Log.i(TAG, "Database combo insertion of " + result.getWord() + " successful :)");
}
这是我的数据库适配器:我试图遵循Android准则......
/**
* SQLite Database. There are many like it but this one is mine...
*
* @author John Doe
* @author Citizen X
* @version 0.2 (pre-beta)
* @see 'http://developer.android.com/reference/android/database/sqlite/package-summary.html'
* @since 0.1 2015-06-17.
*/
public class ResultsDbAdapter {
// Debugging tag
public final static String TAG = "DictionaryDbAdapter";
// Result types
private static final String RESULT_TYPE_ANAGRAM = "anagram";
private static final String RESULT_TYPE_SUBWORD = "subword";
private static final String RESULT_TYPE_COMBO = "combo";
// Handle for helper
ResultsDbHelper helper;
// Constructor gets access to inner helper class
public ResultsDbAdapter(Context context) {
helper = new ResultsDbHelper(context);
}
/* -------------- */
/* --- Helper --- */
/* -------------- */
/**
* SQLite open helper class
*/
static class ResultsDbHelper extends SQLiteOpenHelper {
public static final String TAG = "ResultsDbHelper";
// If you change the database schema, you must increment the database version.
public static final int DATABASE_VERSION = 55;
public static final String DATABASE_NAME = "wordsleuth.db";
/* ------------------------------ */
/* --- Contract and constants --- */
/* ------------------------------ */
/**
* Database contract
*/
public class ResultsDbContract {
// To prevent someone from accidentally instantiating the contract class,
// give it an empty constructor.
public ResultsDbContract() {}
/* --- Inner class that defines the table contents --- */
/*
By implementing the BaseColumns interface, your inner class can inherit a primary key
field called _ID that some Android classes such as cursor adaptors will expect it to have.
It's not required, but this can help your database work harmoniously with the Android
framework.
*/
public abstract class ResultEntry implements BaseColumns {
// Table name
public static final String TABLE_NAME = "results";
// Table columns
public static final String UID = "_id";
public static final String COLUMN_NAME_RESULT_TYPE = "resultype";
public static final String COLUMN_NAME_WORD = "word";
public static final String COLUMN_NAME_WORD_LENGTH = "length";
public static final String COLUMN_NAME_SCRABBLE_POINTS = "scrabblepoints";
public static final String COLUMN_NAME_WORDS_WITH_FRIENDS_POINTS = "wordspoints";
// Table text
private static final String ID_INCREMENT = " INTEGER PRIMARY KEY AUTOINCREMENT";
private static final String TEXT_TYPE = " TEXT";
private static final String INTEGER_TYPE = " INTEGER";
private static final String AND = " AND ";
private static final String COMMA_SEP = ", ";
private static final String PARENTHESIS_LEFT = " (";
private static final String PARENTHESIS_RIGHT = " )";
// Table commands
private static final String CREATE_TABLE = "CREATE TABLE ";
private static final String DROP_TABLE = "DROP TABLE IF EXISTS ";
private static final String DELETE_FROM_ALL = "DELETE * FROM ";
// Table creation
private static final String SQL_CREATE_ENTRIES =
CREATE_TABLE + TABLE_NAME + PARENTHESIS_LEFT + // Create table
UID + ID_INCREMENT + COMMA_SEP + // _id
COLUMN_NAME_RESULT_TYPE + TEXT_TYPE + COMMA_SEP + // result type
COLUMN_NAME_WORD + TEXT_TYPE + COMMA_SEP + // word
COLUMN_NAME_WORD_LENGTH + TEXT_TYPE + COMMA_SEP + // word length
COLUMN_NAME_SCRABBLE_POINTS + TEXT_TYPE + COMMA_SEP + // sc points
COLUMN_NAME_WORDS_WITH_FRIENDS_POINTS + TEXT_TYPE + // wwf points
PARENTHESIS_RIGHT;
// Table deletion
private static final String SQL_DELETE_ENTRIES = DROP_TABLE + TABLE_NAME;
private static final String SQL_DELETE_ALL_ENTRIES = DROP_TABLE + TABLE_NAME;
}
}// End contract
/* ------------------- */
/* --- Constructor --- */
/* ------------------- */
/**
*
* @param context - the context
*/
public ResultsDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
Log.i(TAG, "Database " + DATABASE_NAME + " version " + DATABASE_VERSION + " created");
}
/* -------------------------- */
/* --- Database insertion --- */
/* -------------------------- */
/**
* Insert a result into the database
* @param resultType
* @param word
* @param length
* @param scrabblePoints
* @param wordsPoints
* @return
*/
public long insertData(
// Insertion types // Info
// --------------- --------------
String resultType, // Result type
String word, // The word
String length, // The length
String scrabblePoints, // Scrabble(TM) point value
String wordsPoints // Words With Friends(TM) point value
) {
// Insert data
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COLUMN_NAME_RESULT_TYPE, resultType);
contentValues.put(COLUMN_NAME_WORD, word);
contentValues.put(COLUMN_NAME_WORD_LENGTH, length);
contentValues.put(COLUMN_NAME_SCRABBLE_POINTS, scrabblePoints);
contentValues.put(COLUMN_NAME_WORDS_WITH_FRIENDS_POINTS, wordsPoints);
// Returns -1 if fails, otherwise, returns
return db.insert(TABLE_NAME, null, contentValues);
}//End insertData()
// Handle for helper
ResultsDbHelper helper;
// Constructor gets access to inner helper class
public ResultsDbAdapter(Context context) {
helper = new ResultsDbHelper(context);
}
/* -------------- */
/* --- Helper --- */
/* -------------- */
/**
* SQLite open helper class
*/
static class ResultsDbHelper extends SQLiteOpenHelper {
public static final String TAG = "ResultsDbHelper";
// If you change the database schema, you must increment the database version.
public static final int DATABASE_VERSION = 55;
public static final String DATABASE_NAME = "wordsleuth.db";
/* ------------------------------ */
/* --- Contract and constants --- */
/* ------------------------------ */
/**
* Database contract
*/
public class ResultsDbContract {
// To prevent someone from accidentally instantiating the contract class,
// give it an empty constructor.
public ResultsDbContract() {}
/* --- Inner class that defines the table contents --- */
/*
By implementing the BaseColumns interface, your inner class can inherit a primary key
field called _ID that some Android classes such as cursor adaptors will expect it to have.
It's not required, but this can help your database work harmoniously with the Android
framework.
*/
public abstract class ResultEntry implements BaseColumns {
// Table name
public static final String TABLE_NAME = "results";
// Table columns
public static final String UID = "_id";
public static final String COLUMN_NAME_RESULT_TYPE = "resultype";
public static final String COLUMN_NAME_WORD = "word";
public static final String COLUMN_NAME_WORD_LENGTH = "length";
public static final String COLUMN_NAME_SCRABBLE_POINTS = "scrabblepoints";
public static final String COLUMN_NAME_WORDS_WITH_FRIENDS_POINTS = "wordspoints";
// Table text
private static final String ID_INCREMENT = " INTEGER PRIMARY KEY AUTOINCREMENT";
private static final String TEXT_TYPE = " TEXT";
private static final String INTEGER_TYPE = " INTEGER";
private static final String AND = " AND ";
private static final String COMMA_SEP = ", ";
private static final String PARENTHESIS_LEFT = " (";
private static final String PARENTHESIS_RIGHT = " )";
// Table commands
private static final String CREATE_TABLE = "CREATE TABLE ";
private static final String DROP_TABLE = "DROP TABLE IF EXISTS ";
private static final String DELETE_FROM_ALL = "DELETE * FROM ";
// Table creation
private static final String SQL_CREATE_ENTRIES =
CREATE_TABLE + TABLE_NAME + PARENTHESIS_LEFT + // Create table
UID + ID_INCREMENT + COMMA_SEP + // _id
COLUMN_NAME_RESULT_TYPE + TEXT_TYPE + COMMA_SEP + // result type
COLUMN_NAME_WORD + TEXT_TYPE + COMMA_SEP + // word
COLUMN_NAME_WORD_LENGTH + TEXT_TYPE + COMMA_SEP + // word length
COLUMN_NAME_SCRABBLE_POINTS + TEXT_TYPE + COMMA_SEP + // sc points
COLUMN_NAME_WORDS_WITH_FRIENDS_POINTS + TEXT_TYPE + // wwf points
PARENTHESIS_RIGHT;
// Table deletion
private static final String SQL_DELETE_ENTRIES = DROP_TABLE + TABLE_NAME;
private static final String SQL_DELETE_ALL_ENTRIES = DROP_TABLE + TABLE_NAME;
}
}// End contract
/* ------------------- */
/* --- Constructor --- */
/* ------------------- */
/**
*
* @param context - the context
*/
public ResultsDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
Log.i(TAG, "Database " + DATABASE_NAME + " version " + DATABASE_VERSION + " created");
}
/**
* On creation
* @param db - the database
*/
public void onCreate(SQLiteDatabase db) {
Log.i(TAG, "" + db.getPath() + " created");
db.execSQL(ResultsDbContract.ResultEntry.SQL_CREATE_ENTRIES);
}
/* -------------------------- */
/* --- Database insertion --- */
/* -------------------------- */
/**
* Insert a result into the database
* @param resultType
* @param word
* @param length
* @param scrabblePoints
* @param wordsPoints
* @return
*/
public long insertData(
// Insertion types // Info
// --------------- --------------
String resultType, // Result type
String word, // The word
String length, // The length
String scrabblePoints, // Scrabble(TM) point value
String wordsPoints // Words With Friends(TM) point value
) {
// Insert data
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COLUMN_NAME_RESULT_TYPE, resultType);
contentValues.put(COLUMN_NAME_WORD, word);
contentValues.put(COLUMN_NAME_WORD_LENGTH, length);
contentValues.put(COLUMN_NAME_SCRABBLE_POINTS, scrabblePoints);
contentValues.put(COLUMN_NAME_WORDS_WITH_FRIENDS_POINTS, wordsPoints);
// Returns -1 if fails, otherwise, returns
return db.insert(TABLE_NAME, null, contentValues);
}//End insertData()
}
答案 0 :(得分:3)
您可以实现的最简单,最有效的性能提升之一是管理数据库事务。 For more on Transactions.
这可以通过使用以下内容来实现:
db.beginTransaction();
try {
InsertData();
db.setTransactionSuccessful();
} catch {
//Error in between database transaction
} finally {
db.endTransaction();
}
此外,通过修改到数据库的标准连接字符串可以产生一些提高速度。 This是各种速度提升的绝佳资源,
答案 1 :(得分:-1)
已知在多个插入之间重用SQLiteStatement
可提高插入速度。
SQLiteDatabase db = helper.getWritableDatabase();
db.beginTransaction();
try {
final SQLiteStatement insertStatement = db.compileStatement("INSERT INTO x (a,b) VALUES (?, ?);");
for (Item item : itemsToInsert) {
insertStatement.clearBindings();
insertStatement.bindLong(1, item.getA());
insertStatement.bindString(2, item.getB());
insertStatement.executeInsert();
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
与为每行插入新的插入语句相比,性能提升通常是2-3倍,如果你插入了很多行。