Поиск в базе данных SQLite очень медленный - PullRequest
0 голосов
/ 12 декабря 2018

Я делаю приложение для словаря. Я создал базу данных sqlite с 180 тыс. Слов и значений из импорта csv. При импорте 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;
    }

Код поиска Mainacctivity

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 голосов
/ 12 декабря 2018
  1. Вы должны использовать пакетную вставку, также вы можете просто записывать, сколько времени занимает выполнение операций, например: анализ, запись в базу данных.и попробуйте оптимизировать конкретную операцию.
  2. Чтобы избежать зависаний, выполните вызов БД в фоновом потоке.

Пример пакета: `

public void add_cities(ArrayList<Cities> list) {
        SQLiteDatabase database = this.getWritableDatabase();
        String sql = "INSERT INTO " + TABLE_NAME + " VALUES(?, ?)";
        SQLiteStatement statement = database.compileStatement(sql);
        database.beginTransaction();
        try {
            for (Cities c : list) {
                statement.clearBindings();
                statement.bindLong(1, c.getCityId());
                statement.bindLong(2, c.getCityName());
                statement.execute();
            }
            database.setTransactionSuccessful();
        } finally {
            database.endTransaction();
        }
    }

`

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...