2012-12-27 19 views
7

creo un uso da tavolo come schema:Come migliorare le prestazioni SQLite come dichiarazione

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

Ora il tavolo hanno circa 450.000 fila records.When io uso come dichiarazione In basso a ipod4, la prestazione non è buona: seleziona * da wordIndex dove parola come 'test acces%'; Usa spiegare uscita:

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| 

Può essere che ho bisogno costruire un indice invertito ulteriore per migliorare le prestazioni o ...? Grazie anticipo!

+1

Stai usando solo questo modello per LIKE (cioè inizia con)? –

+0

Sì, solo pattern "aaa%" – ericfang

risposta

10

Gli indici e like non vanno d'accordo nella maggior parte dei database. La cosa migliore è riscrivere la query come una query gamma, se possibile, perché l'indice verrà utilizzato: (. Il tutore aperto è il carattere ASCII immediatamente successivo 'z')

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

Se stai cercando dei pattern all'inizio di una parola (ad esempio '% test'), potresti dover rassegnarti a una scansione completa della tabella.

EDIT:

Indici e like * do` andare d'accordo al giorno d'oggi nella maggior parte dei database in cui i modelli inizia con una costante, in modo da poter fare:

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

Io non sono sicuro al 100% circa SQLite, comunque, quindi controlla il piano di esecuzione per vedere se usa l'indice.

+0

Grazie a Gordon Lionff, funziona davvero. Prima della riscrittura delle query: Tempo di esecuzione: 1.756531 secondo, dopo la riscrittura della query: Tempo di esecuzione: 0,011285 sul mio iPod Touch 4. – ericfang

+0

Tnx ma è case-sensitive! – alizx

5

Prova questo:

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

"~" è il simbolo più grande ASCII.

2

Avrò una risposta leggermente diversa da quella di Gordon Linoff, ma con lo stesso approccio.

Se si desidera mantenere tutti i caratteri che seguono 'accesso di prova' si dovrebbe provare questo:

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