2013-10-24 5 views
1

Я создал таблицу с sqlite для моего приложения corona/lua. Это хэш-таблица с ~ = 700 000 значений. Таблица имеет два столбца, которые являются хэш-кодом (строка) и значением (другая строка). Во время программы мне нужно получить данные несколько раз, предоставив хэш-код.SQLite data retrieve с выбранным слишком длинным

Я использую что-то вроде этого кода, чтобы получить данные:

for p in db:nrows([[SELECT * FROM test WHERE id=']].."hashcode"..[[';]]) do 
    print(p) 
    -- p = returned value -- 
end 

Это утверждение, хотя с душевнобольно слишком много времени, чтобы выполнить

спасибо,

Edit:

Успех! ошибка была с Primare ключевых thing.I задают хэш-код в качестве первичного ключа, как показано ниже, и получить время whent к нормальному:

CREATE TABLE IF NOT EXISTS test (id STRING PRIMARY KEY , array); 

я также подготовил заявления заранее, как вы сказали:

stmt = db:prepare("SELECT * FROM test WHERE id = ?;") 
[...] 
stmt:bind(1,s) 
for p in stmt:nrows() do 

Единственная проблема заключалась в том, что размер файла БД, который был около 18 МБ, пошел 29,5 MB

ответ

0

Убедитесь, что есть индекс на колонке id/Hashcode? Без таких запросов будет медленный, медленный, медленный. Этот индекс, вероятно, должен быть уникальным.

Если только выбрав значение/хэш-код (SELECT value FROM ..), это может быть полезно иметь покрытие индекс над (id, value), как можно избежать дополнительных стремясь данных строк (см SQLite Query Planning). Попробуйте это с и без такого индекса покрытия.

Кроме того, может быть целесообразно использовать кеширование , если один и тот же хэш-код запрашивается несколько раз.

+0

+1 для индекса, -1 для кеширования (редко окупается в sqlite, так как строка будет в кэше процессора в любом случае и не задействован сетевой ввод-вывод.) – finnw

+0

, когда вы говорите, что индекс покрытия означает числовую индекс, как 1,2,3,4 ... было бы полезно? –

+0

@ossumsiul Индекс покрытия является составным индексом, который * также * содержит дополнительные данные, необходимые для результата запроса (который имеет преимущество для уменьшения дополнительного доступа к первичной записи и имеет побочный эффект дублирования физических данных). Например, составной индекс над *, оба * '(id, value)' "покрывает" столбец 'value', хотя для нахождения' value' используется только столбец 'id' (который появляется в WHERE). Статья о планировщике запросов SQLite в сообщении достаточно хорошо объясняет, как это может помочь *. – user2864740

2

Вы должны создать таблицу с id как уникальный первичный ключ; это автоматически сделает индекс.

create table if not exists test 
(
    id text primary key, 
    val text 
); 

Вы не должны создавать утверждения, используя конкатенацию строк; это проблема безопасности, поэтому избегайте попадания в эту привычку. Кроме того, вы должны готовить заявления заранее, при инициализации программы и запускать подготовленные заявления.

Что-то вроде этого ... сначала:

hashcode_query_stmt = db:prepare("SELECT * FROM test WHERE id = ?;") 

то для каждого использования:

hashcode_query_stmt:bind_values(hashcode) 
for p in hashcode_query_stmt:urows() do ... end 
+0

большое спасибо, это помогло –

0

Как уже говорилось, получить что у вас есть индекс по идентификатору.

Если вы не можете изменить схему таблицы Теперь, вы можете добавить индекс специальную:

CREATE INDEX test_id ON test (id); 

О хэшей: если вы вычисления хэшей в вашем программном обеспечении, чтобы ускорить поиски, не надо!

SQLite будет использовать ваши поставляемые хеши как обычные строки/blob. Кроме того, СУБД оптимизированы для эффективного поиска, что может быть значительно улучшено с помощью индексов.

Если ваше хеширование не позволяет сэкономить место, вы тратите время на обработку хэшей процессора в своем приложении.

Смежные вопросы