2012-12-27 27 views
7

我創建一個表使用這種模式:如何提高SQLite的LIKE語句性能

CREATE TABLE wordIndex(id integer primary key, word varchar(128), offset integer, length integer); 
CREATE INDEX word_idx on wordIndex(word); 

現在的表有45萬行records.When我使用Like語句下面就ipod4,表現並不好: 從wordIndex中選擇*,其中的單詞如'test acces%'; 使用EXPLAIN輸出:

explain select * from wordIndex where word like 'test acces%'; 
0|Trace|0|0|0||00| 
1|Goto|0|16|0||00| 
2|OpenRead|0|2|0|4|00| 
3|Rewind|0|14|0||00| 
4|String8|0|2|0|test acces%|00| 
5|Column|0|1|3||00| 
6|Function|1|2|1|like(2)|02| 
7|IfNot|1|13|1||00| 
8|Rowid|0|4|0||00| 
9|Column|0|1|5||00| 
10|Column|0|2|6||00| 
11|Column|0|3|7||00| 
12|ResultRow|4|4|0||00| 
13|Next|0|4|0||01| 
14|Close|0|0|0||00| 
15|Halt|0|0|0||00| 
16|Transaction|0|0|0||00| 
17|VerifyCookie|0|2|0||00| 
18|TableLock|0|2|0|wordIndex|00| 
19|Goto|0|2|0||00| 

可能是我需要建立一個額外的倒排索引,以提高性能還是...? 感謝提前!

+1

是否只使用這種模式像(即開頭)? –

+0

是的,只是「aaa%」模式 – ericfang

回答

10

索引和like在大多數數據庫中不相處。最好的辦法是重寫查詢爲範圍查詢,如果可能的話,因爲索引將被用於:(開括號是ASCII字符立即「Z」以下)

select * 
from wordIndex 
where word between 'test acces' and 'test acces{' 

如果你在單詞的開頭尋找模式(比如說'%test'),那麼你可能不得不重新開始全表掃描。

編輯:

指標和like * do`相處時下大多數數據庫模式以恆定啓動時,所以你可以做:

select * 
from wordIndex 
where word like 'test acces%' ; 

我不是100%地肯定SQLite,但是,檢查執行計劃,看它是否使用索引。

+0

謝謝Gordon Lionff,它的工作很簡單。查詢重寫之前:執行時間:1.756531秒,查詢重寫後:執行時間:0.011285在我的iPod Touch上4。 – ericfang

+0

Tnx但區分大小寫! – alizx

5

試試這個:

SELECT * FROM wordIndex 
WHERE word COLLATE NOCASE BETWEEN @SearchString AND @SearchString || '~~~~~~~~~~' 

「〜」 是最大的ASCII符號。

2

我會和Gordon Linoff的答案略有不同,但採用相同的方法。

如果你想保持遵循「測試ACCES」的任何字符,你應該試試這個:

SELECT * FROM wordIndex 
WHERE word > 'test acces' AND word < 'test accet';