Domanda

Abbiamo una query che esegue una tabella abbastanza grande che purtroppo deve usare LIKE '% ABC%' su un paio di campi varchar in modo che l'utente possa cercare nomi parziali, ecc. SQL Server 2005

L'aggiunta di un indice su questi campi varchar sarebbe di aiuto in termini di prestazioni delle query selezionate quando si utilizza LIKE o fondamentalmente ignorerebbe gli indici e farebbe una scansione completa in quei casi?

Altri modi possibili per migliorare le prestazioni quando si utilizza LIKE?

È stato utile?

Soluzione

Solo se aggiungi la ricerca full-text a quelle colonne e usi le funzionalità di query full-text di SQL Server.

Altrimenti, no, un indice non aiuta.

Altri suggerimenti

Puoi potenzialmente vedere miglioramenti delle prestazioni aggiungendo indici, dipende molto dalle specifiche :)

Quanto della dimensione totale della riga sono le colonne previste? Quante righe ti aspetti di abbinare? Devi restituire tutte le righe corrispondenti al predicato o solo le prime 1 o le prime n righe?

Se stai cercando valori con alta selettività / unicità (quindi poche righe da restituire) e le colonne predicate sono una porzione piccola dell'intera dimensione della riga, un indice potrebbe essere abbastanza utile. Sarà comunque una scansione, ma il tuo indice si adatta a più righe per pagina rispetto alla tabella di origine.

Ecco un esempio in cui la dimensione totale della riga è molto maggiore della dimensione della colonna in cui cercare:

create table t1 (v1 varchar(100), b1 varbinary(8000))
go
--add 10k rows of filler
insert t1 values ('abc123def', cast(replicate('a', 8000) as varbinary(8000)))
go 10000
--add 1 row to find
insert t1 values ('abc456def', cast(replicate('a', 8000) as varbinary(8000)))
go

set statistics io on 
go
select * from t1 where v1 like '%456%'
--shows 10001 logical reads

--create index that only contains the column(s) to search across
create index t1i1 on t1(v1)
go
select * from t1 where v1 like '%456%'
--or can force to 
--shows 37 logical reads

Se guardi il piano di esecuzione effettivo puoi vedere il motore ha scansionato l'indice e fatto una ricerca nei segnalibri sulla riga corrispondente. Oppure puoi dire direttamente all'ottimizzatore di utilizzare l'indice, se non avesse deciso di utilizzare questo piano da solo: seleziona * da t1 con (indice (t1i1)) dove v1 come '% 456%'

Se hai un sacco di colonne per cercare solo alcune altamente selettive, puoi creare più indici e utilizzare un approccio di riduzione. Per esempio. prima determina un set di ID (o qualunque sia il tuo PK) dal tuo indice altamente selettivo, quindi cerca le tue colonne meno selettive con un filtro contro quel piccolo set di PK.

Se hai sempre bisogno di restituire un ampio set di righe, staresti quasi sicuramente meglio con una scansione della tabella.

Quindi le possibili ottimizzazioni dipendono molto dalle specifiche della definizione della tabella e dalla selettività dei dati.

HTH! -Adrian

L'unico altro modo (oltre all'utilizzo dell'indicizzazione full-text) è possibile migliorare le prestazioni è utilizzare "LIKE ABC%" - non aggiungere il carattere jolly su entrambe le estremità del termine di ricerca - in tal caso, un indice potrebbe funzionare.

Se i tuoi requisiti sono tali che devi avere i caratteri jolly su entrambe le estremità del termine di ricerca, sei sfortunato ...

Marc

Come '% ABC%' eseguirà sempre una scansione completa della tabella. Non c'è modo di aggirare questo.

Hai un paio di approcci alternativi. Innanzitutto la ricerca full-text, è davvero progettata per questo tipo di problema, quindi esaminerò prima quello.

In alternativa, in alcune circostanze potrebbe essere opportuno denormalizzare i dati e pre-elaborare i campi target in token appropriati, quindi aggiungere questi possibili termini di ricerca in uno separato a molte tabelle di ricerca. Ad esempio, se i miei dati consistessero sempre in un campo contenente il modello "AAA / BBB / CCC" e i miei utenti cercassero su BBB, lo toccherei con l'inserimento / aggiornamento (e rimuovo con l'eliminazione). Questo sarebbe anche uno di quei casi in cui l'uso dei trigger, piuttosto che il codice dell'applicazione, sarebbe molto preferito.

Devo sottolineare che questa non è davvero una tecnica ottimale e dovrebbe essere utilizzata solo se i dati sono una buona corrispondenza per l'approccio e per qualche motivo non si desidera utilizzare la ricerca full-text (e le prestazioni del database simili la scansione è davvero inaccettabile). È anche probabile che produca mal di testa da manutenzione più in là.

crea statistiche su quella colonna. sql server 2005 ha ottimizzato la ricerca nella stringa in modo che tu possa trarne beneficio.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top