搜索SQLite数据库非常慢

时间:2018-12-12 19:32:29

标签: android sqlite full-text-search

我正在制作一个字典应用程序。我已经创建了一个带csv导入的180k个单词和含义数据的sqlite数据库。导入csv时,需要5分钟的时间才能导入到数据库中。使用FTS4创建的数据库。

我的第一个问题是

1)如何用更少的时间导入?

当我在搜索视图中键入一个单词时,光标冻结5秒钟,然后在列表视图中显示建议。

我的秒数是

2)在不冻结的情况下更快地显示建议

对不起,我的英语不好

public class DatabaseTable {

private static final String TAG = "DictionaryDatabase";

//The columns we'll include in the dictionary table
public static final String COL_WORD = "WORD";
public static final String COL_DEFINITION = "DEFINITION";
public static final String COL_PRONUNCIATION = "PRONUNCIATION";
public static final String COL_EXAMPLE = "EXAMPLE";
public static final String COL_SYNONYMS = "SYNONYMS";
public static final String COL_COMMON_MEAN = "COMMON_MEAN";
public static final String COL_MORE_MEAN = "MORE_MEAN";

private static final String DATABASE_NAME = "DICTIONARY";
private static final String FTS_VIRTUAL_TABLE = "FTS";
private static final int DATABASE_VERSION = 1;

public final DatabaseOpenHelper mDatabaseOpenHelper;

public DatabaseTable(Context context) {
    mDatabaseOpenHelper = new DatabaseOpenHelper(context);
}

public static class DatabaseOpenHelper extends SQLiteOpenHelper {

    private final Context mHelperContext;
    private SQLiteDatabase mDatabase;

    private static final String FTS_TABLE_CREATE =
            "CREATE VIRTUAL TABLE " + FTS_VIRTUAL_TABLE +
                    " USING fts4 (" +
                    COL_WORD + ", " +
                    COL_COMMON_MEAN + ", " +
                    COL_PRONUNCIATION + ", " +
                    COL_MORE_MEAN + ", " +
                    COL_DEFINITION + ", " +
                    COL_SYNONYMS + ", " +
                    COL_EXAMPLE + ")";

    DatabaseOpenHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        mHelperContext = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        mDatabase = db;
        mDatabase.execSQL(FTS_TABLE_CREATE);

        loadDictionary();

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                + newVersion + ", which will destroy all old data");
        db.execSQL("DROP TABLE IF EXISTS " + FTS_VIRTUAL_TABLE);
        onCreate(db);
    }


    private void loadDictionary() {
        new Thread(new Runnable() {
            public void run() {
                try {
                    loadWords();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }).start();
    }

    private void loadWords() throws IOException {
        final Resources resources = mHelperContext.getResources();
        //InputStream inputStream = resources.openRawResource();
        BufferedReader reader = new BufferedReader(new InputStreamReader(mHelperContext.getAssets().open("definition1.csv"), "UTF-8"));

        try {
            String line;
            while ((line = reader.readLine()) != null) {
                String[] strings = TextUtils.split(line, "\\|");
                if (strings.length != 7) {
                    Log.d("CSVParser", "Skipping Bad CSV Row");
                    continue;
                }
                long id = addWord(strings[0].trim(), strings[1].trim(), strings[2].trim(), strings[3].trim(), strings[4].trim(), strings[5].trim(), strings[6].trim());
                if (id < 0) {
                    Log.e(TAG, "unable to add word: " + strings[0].trim());
                }
            }
        } finally {
            reader.close();
        }
    }

    public long addWord(String word, String common_mean, String pronuntiation, String more_mean, String definition, String synonym, String example) {
        ContentValues initialValues = new ContentValues();
        initialValues.put(COL_WORD, word);
        initialValues.put(COL_COMMON_MEAN, common_mean);
        initialValues.put(COL_PRONUNCIATION, pronuntiation);
        initialValues.put(COL_MORE_MEAN, more_mean);
        initialValues.put(COL_DEFINITION, definition);
        initialValues.put(COL_SYNONYMS, synonym);
        initialValues.put(COL_EXAMPLE, example);
        Log.d("inserting", word);

        return mDatabase.insert(FTS_VIRTUAL_TABLE, null, initialValues);
    }

    public Cursor getWordMatches(String query, String[] columns) {
        String selection = COL_WORD + " MATCH ?";
        String[] selectionArgs = new String[]{query + "ORDER BY rank"};

        return query(selection, selectionArgs, columns);
    }

    private Cursor query(String selection, String[] selectionArgs, String[] columns) {
        SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
        builder.setTables(FTS_VIRTUAL_TABLE);

        Cursor cursor = builder.query(getReadableDatabase(),
                columns, selection, selectionArgs, null, null, null);

        if (cursor == null) {
            return null;
        } else if (!cursor.moveToFirst()) {
            cursor.close();
            return null;
        }
        return cursor;
    }

主要活动搜索代码

private SearchView.OnQueryTextListener onQueryTextListener =
        new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {

                Toast.makeText(MainActivity.this, "Problem in Fetching Deals",
                        Toast.LENGTH_LONG).show();
                return true;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                getDealsFromDb(newText);
                return true;
            }

            private void getDealsFromDb(final String searchText) {

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {

                        deals=databaseTable.mDatabaseOpenHelper.getallword(searchText);
                        SuggestionAdapter1 adapter=new SuggestionAdapter1
                                (MainActivity.this, deals, R.layout.suggestion_item_layout);
                        listView.setAdapter(adapter);


                    }
                });




            }
        };

适配器类

public class SuggestionAdapter1 extends ArrayAdapter{
    private List<ItemObject> dataList;
    private Context mContext;
    private int searchResultItemLayout;

    public SuggestionAdapter1(Context context, List<ItemObject> resource,
                              int rid) {
        super(context, rid, resource);
        dataList = resource;
        mContext = context;
        searchResultItemLayout = rid;
    }

    @Override
    public int getCount() {
        return dataList.size();
    }

    @Override
    public ItemObject getItem(int position) {
        return dataList.get(position);
    }

    @Override
    public View getView(int position, View view, @NonNull ViewGroup parent) {

        if (view == null) {
            view = LayoutInflater.from(parent.getContext())
                    .inflate(searchResultItemLayout, parent, false);
        }

        ItemObject di = getItem(position);

        TextView dealsTv = (TextView) view.findViewById(R.id.eng);
        dealsTv.setText(di.getId());

        TextView cashbackTv = (TextView) view.findViewById(R.id.bng);
        cashbackTv.setText(di.getWord());




        return view;
    }

}

1 个答案:

答案 0 :(得分:1)

  1. 您应该使用批处理插入,也可以只记录执行操作所需的时间,例如:解析,写入数据库数据集。并尝试优化特定操作。
  2. 为避免冻结,请在后台线程上执行对数据库的调用。

批次示例: `

Neo4jClient

`