2011-10-13 20 views
6

Vorrei query indice come x like '%abc%'Come creare un indice di testo per la ricerca '% abc%'?

Se ho una tabella come la seguente

create table t 
(
    data varchar(100) 
); 

voglio creare un indice per essere in grado di effettuare le seguenti operazioni in modo efficiente:

select * from t where contains('%abc%'); 

E questo:

select * from t where contains('abc%'); 

I voglio anche che questa tabella sia aggiornata dal vivo.

Come si crea un indice di questo tipo? (Ho la sensazione che ho bisogno di un indice ctxcat, ma sono confuso su quali opzioni ho bisogno di dargli)

Sto usando Oracle 10g.

risposta

7

vorrei utilizzare questo (set si min e la lunghezza massima di appropriarsi dei valori)

BEGIN 
    ctx_ddl.create_preference ('FT_WL', 'BASIC_WORDLIST'); 
    ctx_ddl.set_attribute  ('FT_WL', 'substring_index', 'YES'); 
    ctx_ddl.set_attribute  ('FT_WL', 'prefix_index',  'YES'); 
    ctx_ddl.set_attribute  ('FT_WL', 'prefix_min_length', 1); 
    ctx_ddl.set_attribute  ('FT_WL', 'prefix_max_length', 6); 
    END; 

CREATE INDEX fulltext_idx ON tmp_fulltext (fulltext) 
INDEXTYPE IS CTXSYS.CTXCAT 
PARAMETERS ('WORDLIST FT_WL') 

I parametri sono spiegati qui Oracle Text Reference

e vedere questa domanda su come gestire l'aggiornamento e su come l'indice potrebbe non essere più veloce di una scansione completa con dati di cardinalità elevati:

PL/SQL Performance Tuning for LIKE '%...%' Wildcard Queries

+1

Grazie per la risposta. Solo alcune domande: 'prefix_index' per le query' abc% 'e 'substring_index' per le query'% abc% '? E l'indice della sottostringa per default indice tutte le sottostringhe? Inoltre, come posso usare questo indice? Will 'contiene (col, '% abc%')' e 'contiene (col, 'abc%')' fa il trucco? – Clinton

+0

Sì, quelle ricerche funzioneranno, sono state aggiornate con un link che può spiegarlo meglio di me, ma essenzialmente i parametri vengono utilizzati per migliorare le prestazioni esattamente di quel tipo di ricerca. –

0

guardando il tuo problema se il database è grande, allora si può usare Sphinx Search

Sfinge è un server di ricerca a testo integrale open source, progettato da zero con le prestazioni, la pertinenza (aka la ricerca di qualità), e la semplicità di integrazione in mente. È scritto in C++ e funziona su Linux (RedHat, Ubuntu, ecc.), Windows, MacOS, Solaris, FreeBSD e pochi altri sistemi

+0

Questo sembra interessante, ma purtroppo mi sono bloccato con Oracle 10g. – Clinton

+0

Credetemi è veloce e potete anche aggiornare gli indici degli aggiornamenti .... – Wazzzy

0

Puoi farlo in Oracle solo se hai l'opzione intermedia/Oracle Text sul server ...

per esempio, si potrebbe usare

create index t_index_data on t(data) 
indextype is ctxsys.context 
parameters ('DATASTORE CTXSYS.DEFAULT_DATASTORE'); 

non sono sicuro se è necessario cambiare il tipo varchar2(100)-clob.

Per i dettagli e le opzioni/esempio per quanto riguarda questo tipo di indici vedono http://download.oracle.com/docs/cd/A91202_01/901_doc/text.901/a90122/ind4.htm

+0

Siete sicuri che questi sottostringhe degli indici? Ho letto il documento e sembra che abbia bisogno di una "preferenza" "SUBSTRING_INDEX" o qualcosa del genere. Puoi dare un esempio di codice che fa quello che sto cercando, incluso l'indice di sottostringa? – Clinton

+0

potresti avere ragione riguardo la preferenza - Non ho un server Oracle con quelle opzioni disponibili quindi non posso testarlo ... – Yahia

1

Sì, è necessario creare un ambiente prima di poter creare indici di dominio. Devi aver bisogno di ctxsys utente e ctxapp previliges per crearlo. Segui i passaggi spiegati nel link qui sotto per averne uno per il tuo ambiente. Questo utente non viene creato per impostazione predefinita durante l'installazione di Oracle.

http://www.oraclebin.com/2012/12/creating-environment-for-ctxsys.html

Una volta che hai i tutte le sovvenzioni e pacchetti che è possibile creare le preferenze e indice, come illustrato.

SQL> begin 
    2 ctx_ddl.create_preference('SUBSTRING_PREF', 'BASIC_WORDLIST'); 
    3 ctx_ddl.set_attribute('SUBSTRING_PREF', 'SUBSTRING_INDEX','TRUE'); 
    4 end; 
    5/

Ora creare un indice di dominio come mostrato.

SQL> create index test_idx on test(object_name) 
    2 indextype is ctxsys.context parameters ('wordlist SUBSTRING_PREF MEMORY 50M'); 

Index created. 

select * from test where contains(object_name,'%EXEC%') > 0; 

Vedere il collegamento di seguito che spiega questo con il piano di esecuzione.

Riferimenti: http://www.oraclebin.com/2012/12/oracle-text-and-domain-indexes.html

Problemi correlati