2012-10-21 9 views
5

Ive stava provando a ottenere sqlite per usare un indice con un simile senza alcun risultato. Ho provato a collezionare nocase e ancora senza fortuna. Qualcuno ha qualche idea su come ottenere sqlite per fare come colpire un indice. Grazie in anticiposqlite che non utilizza l'indice con la query simile

DROP TABLE IF EXISTS "test"; 
DROP TABLE IF EXISTS "test2"; 
DROP TABLE IF EXISTS "test3"; 
create table test(name TEXT COLLATE NOCASE); 
create table test2(name TEXT); 
create table test3(name TEXT); 
create index idx_test_name on test(name); 
create index idx_test2_name on test2(name); 
create index idx_test3_name on test3(name COLLATE NOCASE); 
insert into test(name) values('dan'); 
insert into test2(name) values('dan'); 
insert into test3(name) values('dan'); 
--explain query plan select * from test where name like 'test%' 
-- explain query plan select * from test2 where name like 'test%' 
-- explain query plan select * from test3 where name like 'test%' 
+0

Avere un indice non garantisce che verrà utilizzato. –

risposta

1

In SQLite 3.6.23.1, l'indice test viene utilizzato:

> explain query plan select * from test where name like 'test%'; 
TABLE test WITH INDEX idx_test_name 

> explain query plan select * from test2 where name like 'test%'; 
TABLE test2 

> explain query plan select * from test3 where name like 'test%'; 
TABLE test3 

Con una versione di sviluppo di SQLite 3.7.15, entrambi test 's e test3' s indici vengono utilizzati (indice su test2 è utilizzato per la scansione , non la ricerca):

> explain query plan select * from test where name like 'test%'; 
SEARCH TABLE test USING COVERING INDEX idx_test_name (name>? AND name<?) (~31250 rows) 

> explain query plan select * from test2 where name like 'test%'; 
SCAN TABLE test2 USING COVERING INDEX idx_test2_name (~500000 rows) 

> explain query plan select * from test3 where name like 'test%'; 
SEARCH TABLE test3 USING COVERING INDEX idx_test3_name (name>? AND name<?) (~31250 rows) 

Quindi la risposta è di aggiornare SQLite.

+0

Grazie per quello, stavo usando l'estensione firefox per provare quale era una versione precedente. Usando una versione più recente funziona – aboutme

11

Citazione dalla lista posta SQLite (http://www.mail-archive.com/[email protected]/msg27760.html)

COME è caso- insensibile per impostazione predefinita. Per fare in modo che utilizzi l'indice, è necessario che l'indice sia insensibile al maiuscolo:

CREATE INDEX test_name ON test (nome COLLATE NOCASE);

effettuate SIMILE-sensitive:

PRAGMA case_sensitive_like = 1;

+0

Anche sul documento http://www.sqlite.org/optoverview.html – Himanshu

+0

Salve, grazie per le repliche di tutti, tuttavia dopo aver testato il collate nocase sull'indice, l'indice non è ancora in uso.Ho aggiornato il mio codice di esempio con un test3 per testare lo scenario se qualcuno vuole provarlo. Altre idee? – aboutme

0

Dal docs:

Condizioni che sono composti dell'operatore LIKE o GLOB volte può essere utilizzato per vincolare indici. Esistono molte condizioni per questo utilizzo:

  • Il lato sinistro dell'operatore LIKE o GLOB deve essere il nome di una colonna indicizzata con affinità TEXT.
  • Il lato destro di LIKE o GLOB deve essere un letterale stringa o un parametro associato a un valore letterale stringa che non inizia con un carattere jolly.
  • La clausola ESCAPE non può essere visualizzata sull'operatore LIKE.
  • Le funzioni integrate utilizzate per implementare LIKE e GLOB non devono essere state sovraccaricate utilizzando l'API sqlite3_create_function().
  • Per l'operatore GLOB, la colonna deve essere indicizzata utilizzando la sequenza di confronto BINARY incorporata.
  • Per l'operatore LIKE, se la modalità case_sensitive_like è abilitata, la colonna deve essere indicizzata utilizzando la sequenza di confronto BINARY oppure se la modalità case_sensitive_like è disabilitata, la colonna deve essere indicizzata utilizzando la sequenza di confronto NOCASE incorporata.
Problemi correlati