2013-10-24 53 views
1

我已經創建了一個與我的corona/lua應用程序的sqlite表。它是一個〜〜700 000個值的散列表。該表有兩列,分別是hashcode(一個字符串)和值(另一個字符串)。在程序期間,我需要通過提供散列碼來多次獲取數據。SQLite數據檢索與選擇需要太長

我用這樣的代碼來獲取數據:

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

此語句雖然採取瘋狂太多的時間來執行

感謝,

編輯:

成功! 的錯誤是設置的哈希碼爲像下面的主鍵primare關鍵的事兒。和檢索時間了when正常:

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 MB,去29,5 MB

回答

0

確保有一個指數id /哈希碼列?沒有這樣的查詢將會是慢,慢,慢。這個指數應該是獨一無二的。

如果僅選擇值/哈希碼(SELECT value FROM ..),它可能是有益的具有覆蓋索引超過(id, value)作爲能夠避免額外尋求的行數據(見SQLite Query Planning)。嘗試使用和不使用這種覆蓋指數。

此外,如果多次查詢相同的哈希碼,則可能值得使用高速緩存

+0

+1的索引,-1緩存(很少在sqlite的回報,因爲該行會在CPU緩存反正沒有網絡I/O參與。) – finnw

+0

當你說覆蓋索引你的意思是一個數字索引,像1,2,3,4 ...會有幫助嗎? –

+0

@ossumsiul覆蓋索引是* *也包含該查詢結果(其具有減輕主記錄的額外的訪問的益處,並具有重複的物理數據的副作用)所需的附加數據的複合索引。例如,一個化合物指數超過*兩者*'(ID,值)'「涵蓋」的'value'列,即使只有'id'柱(其出現在WHERE)用於找到'value'。在後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

如前所述,獲得確保您有ID的索引。

如果你現在不能改變表模式,你可以添加一個索引特設:如果計算在軟件,以加快搜索速度,不要哈希:

CREATE INDEX test_id ON test (id); 

關於哈希!

的SQLite會使用你提供的哈希任何常規字符串/斑點。此外,RDBMS針對高效搜索進行了優化,這可以通過索引大大提高。

除非你的散列以節省空間,你在你的應用程序浪費處理器時間計算哈希值。