Struttura di un indice full-text
Comprendere a fondo la struttura di un indice full-text è fondamentale per comprendere il funzionamento del motore di ricerca full-text. In questo argomento viene utilizzato come esempio l'estratto seguente della tabella Document in Adventure Works. In questo estratto vengono visualizzate solo due colonne, la colonna DocumentID e la colonna Title, e tre righe della tabella.
In questo esempio si suppone che nella colonna Title sia stato creato un indice full-text.
DocumentID |
Title |
---|---|
1 |
Crank Arm and Tire Maintenance |
2 |
Front Reflector Bracket and Reflector Assembly 3 |
3 |
Front Reflector Bracket Installation |
Nella tabella seguente, Fragment 1, viene illustrato il contenuto dell'indice full-text creato nella colonna Title della tabella Document. Gli indici full-text contengono più informazioni rispetto a quelle riportate in questa tabella. La tabella è una rappresentazione logica di un indice full-text e ha solo scopo illustrativo. Per ottimizzare l'utilizzo del disco, le righe vengono archiviate in un formato compresso.
Si noti che i dati sono stati invertiti dai documenti originali. Questa inversione è dovuta al fatto che le parole chiave vengono mappate agli ID documento. Per questo motivo, un indice full-text viene spesso definito come un indice invertito.
Si noti inoltre che la parola chiave "and" è stata rimossa dall'indice full-text, trattandosi di una parola non significativa, e che la rimozione di tali parole da un indice full-text può contribuire a risparmiare spazio su disco, migliorando di conseguenza le prestazioni delle query. Per ulteriori informazioni sulle parole non significative, vedere Parole non significative ed elenchi di parole non significative.
Fragment 1
Parola chiave |
ColId |
DocId |
Occurrence |
---|---|---|---|
Crank |
1 |
1 |
1 |
Arm |
1 |
1 |
2 |
Tire |
1 |
1 |
4 |
Maintenance |
1 |
1 |
5 |
Front |
1 |
2 |
1 |
Front |
1 |
3 |
1 |
Reflector |
1 |
2 |
2 |
Reflector |
1 |
2 |
5 |
Reflector |
1 |
3 |
2 |
Bracket |
1 |
2 |
3 |
Bracket |
1 |
3 |
3 |
Assembly |
1 |
2 |
6 |
3 |
1 |
2 |
7 |
Installation |
1 |
3 |
4 |
La colonna Parola chiave contiene la rappresentazione di un singolo token estratto al momento dell'indicizzazione. I word breaker stabiliscono il modo in cui un token viene determinato.
La colonna ColId contiene un valore che corrisponde a una particolare colonna con indicizzazione full-text.
La colonna DocId contiene valori per un integer a otto byte mappato a un determinato valore chiave full-text in una tabella con indicizzazione full-text. Questo mapping è necessario se la chiave full-text non è un tipo di dati integer. In questi casi, i mapping tra i valori chiave full-text e i valori DocId vengono mantenuti in una tabella separata denominata DocId Mapping. Per eseguire una query per questi mapping utilizzare la stored procedure di sistema sp_fulltext_keymappings. Per soddisfare una condizione di ricerca, è necessario creare un join tra i valori DocId della tabella precedente e la tabella DocId Mapping per recuperare le righe dalla tabella di base su cui viene eseguita la query. Se il valore della chiave full-text della tabella di base è di tipo integer, il valore viene utilizzato direttamente come DocId e non è necessario alcun mapping. Pertanto, l'utilizzo di valori chiave full-text di tipo integer può contribuire all'ottimizzazione delle query full-text.
La colonna Occurrence contiene un valore di tipo integer. Per ogni valore DocId è presente un elenco di valori di occorrenza corrispondenti agli offset relativi di una particolare parola chiave all'interno di DocId. I valori di occorrenza sono utili per determinare le corrispondenze di frase o prossimità, ad esempio frasi con valori di occorrenza numericamente adiacenti. Sono inoltre utili per calcolare i punteggi di pertinenza, ad esempio il numero di occorrenze di una parola chiave in un DocId può essere utilizzato per l'assegnazione del punteggio.
Frammenti di indice full-text
L'indice full-text logico viene in genere suddiviso tra più tabelle interne. Ogni tabella interna viene definita un frammento di indice full-text. Alcuni di questi frammenti potrebbero contenere dati più recenti di altri. Ad esempio, se un utente aggiorna la riga seguente il cui DocId è 3 e per la tabella è impostato il rilevamento automatico delle modifiche, viene creato un nuovo frammento.
DocumentID |
Title |
---|---|
3 |
Rear Reflector |
Nell'esempio seguente, Fragment 2, il frammento contiene dati più recenti su DocId 3, rispetto a Fragment 1. Pertanto, quando viene eseguita una query per "Rear Reflector" i dati di Fragment 2 vengono utilizzati per DocId 3. Ogni frammento viene contrassegnato con un timestamp di creazione su cui è possibile eseguire query tramite la vista del catalogo sys.fulltext_index_fragments.
Fragment 2
Parola chiave |
ColId |
DocId |
Occ |
---|---|---|---|
Rear |
1 |
3 |
1 |
Reflector |
1 |
3 |
2 |
Come si può vedere da Fragment 2, le query full-text devono essere eseguite internamente su ogni frammento e le voci più obsolete devono essere eliminate. Un numero eccessivo di frammenti di indice full-text nell'indice full-text può causare un calo sensibile delle prestazioni di esecuzione delle query. Per ridurre il numero di frammenti, riorganizzare il catalogo full-text tramite l'opzione REORGANIZE dell'istruzione ALTER FULLTEXT CATALOGTransact-SQL. Questa istruzione consente di eseguire un'unione nell'indice master, ovvero un'unione dei frammenti in un singolo frammento più grande e la rimozione di tutte le voci obsolete dall'indice full-text.
Dopo essere stato riorganizzato, l'indice di esempio dovrebbe contenere le righe seguenti:
Parola chiave |
ColId |
DocId |
Occ |
---|---|---|---|
Crank |
1 |
1 |
1 |
Arm |
1 |
1 |
2 |
Tire |
1 |
1 |
4 |
Maintenance |
1 |
1 |
5 |
Front |
1 |
2 |
1 |
Rear |
1 |
3 |
1 |
Reflector |
1 |
2 |
2 |
Reflector |
1 |
2 |
5 |
Reflector |
1 |
3 |
2 |
Bracket |
1 |
2 |
3 |
Assembly |
1 |
2 |
6 |
3 |
1 |
2 |
7 |
Vedere anche