Ricerca nel testo completo

Si applica a:SQL ServerDatabase SQL di AzureIstanza gestita di SQL di Azure

In SQL Server e nel database SQL di Azure la ricerca full-text consente ad applicazioni e utenti di eseguire query full-text su dati di tipo carattere in tabelle di SQL Server.

Modifiche di rilievo nel SQL Server 2025

SQL Server 2025 (17.x) introduce modifiche di rilievo a Full-Text Ricerca.

Per ulteriori informazioni consulta:

Attività di base

Questo articolo offre una panoramica della ricerca full-text e descrive i componenti e l'architettura di questa funzionalità. Per iniziare subito, ecco le attività di base.

La ricerca full-text è un componente facoltativo del motore di database di SQL Server. Se non selezioni Full-Text Search durante l'installazione di SQL Server, puoi aggiungerla in seguito eseguendo nuovamente il programma di installazione.

Panoramica

Un indice full-text include una o più colonne basate su caratteri in una tabella. Queste colonne possono avere uno dei tipi di dati seguenti: char, varchar, nchar, nvarchar, text, ntext, image, xml o varbinary(max) e FILESTREAM. Ogni indice full-text consente di indicizzare una o più colonne della tabella e ciascuna colonna può essere utilizzata con una lingua specifica.

Attraverso le query full-text è possibile eseguire ricerche linguistiche sui dati di testo contenuti negli indici full-text, usando parole e frasi in base alle regole di una determinata lingua, come ad esempio l'inglese o il giapponese. Le query in testo completo possono includere parole e frasi di base o più forme di una parola o frase. Una query full-text restituisce qualsiasi documento contenente almeno una corrispondenza, nota anche come riscontro. Si ottiene una corrispondenza quando un documento di destinazione contiene tutti i termini specificati nella query full-text e soddisfa qualsiasi altra condizione di ricerca, come ad esempio la distanza entro i termini corrispondenti.

Query di ricerca full-text

Dopo l'aggiunta delle colonne a un indice full-text, gli utenti e le applicazioni possono eseguire query full-text sul testo contenuto all'interno delle colonne. Queste query possono consentire la ricerca delle seguenti condizioni:

  • Una o più parole o frasi specifiche (termine semplice)
  • Parola o frase in cui le parole iniziano con il testo specificato (termine di prefisso)
  • Forme flesse di una determinata parola (termine di generazione)
  • Una parola o frase vicina a un'altra parola o frase (termine di prossimità)
  • Sinonimi di una parola specifica (thesaurus)
  • Parole o frasi che usano valori ponderati (termine ponderato)

Per le query di ricerca full-text non viene fatta distinzione tra maiuscole e minuscole. Ad esempio, dalla ricerca di Aluminum o aluminum vengono restituiti gli stessi risultati.

Le query full-text usano un piccolo insieme di predicati Transact-SQL (CONTAINS e FREETEXT) e funzioni (CONTAINSTABLE e FREETEXTTABLE). Tuttavia, gli obiettivi di ricerca di un determinato scenario aziendale influiscono sulla struttura delle query full-text. Ad esempio:

  • Per cercare un prodotto in un sito Web di e-commerce:

    SELECT product_id
    FROM products
    WHERE CONTAINS ((product_description), '"Snap Happy 100EZ" OR FORMSOF(THESAURUS,"Snap Happy") OR "100EZ"')
          AND product_cost < 200;
    
  • Per trovare i candidati di lavoro che hanno esperienza con SQL Server:

    SELECT candidate_name,
           SSN
    FROM candidates
    WHERE CONTAINS ((candidate_resume), '"SQL Server"')
          AND candidate_division = 'DBA';
    

Per altre informazioni, vedere Esecuzione della query con ricerca Full-Text.

Confronto tra query di ricerca full-text e il predicato LIKE

Contrariamente alla ricerca full-text, il predicato LIKE di Transact-SQL funziona unicamente con modelli di caratteri. Non è inoltre possibile utilizzare il predicato LIKE per eseguire query su dati binari formattati. Inoltre, l'esecuzione di una query LIKE su una grande quantità di dati di testo non strutturati è molto più lenta dell'esecuzione di una query full-text equivalente sugli stessi dati. Una LIKE query su milioni di righe di dati testuali può richiedere minuti per essere restituita. Al contrario, una query a testo intero può richiedere solo pochi secondi o meno rispetto agli stessi dati, a seconda del numero di righe restituite.

Architettura della ricerca a testo completo

L'architettura della ricerca full-text è costituita dai processi seguenti:

  • Processo di SQL Server (sqlservr.exe).

  • Processo host del daemon di filtri (fdhost.exe).

    Per motivi di sicurezza, un processo separato chiamato host del daemon di filtro carica filtri e separatori di parole. Il fdhost.exe processo è creato da un servizio launcher FDHOST (MSSQLFDLauncher). Funziona con le credenziali di sicurezza dell'account del servizio launcher FDHOST. Pertanto, il servizio di avvio FDHOST deve essere in esecuzione affinché l'indicizzazione full-text e le query full-text funzionino. Per informazioni su come impostare l'account di servizio per questo servizio, vedi Imposta l'account di servizio per il Filtro Daemon Launcher a testo completo.

In questi due processi sono inclusi i componenti dell'architettura della ricerca full-text, La figura seguente riepiloga questi componenti e le relative relazioni. I componenti vengono descritti dopo l'illustrazione.

Schema dell'architettura della ricerca a testo integrale.

Processo di SQL Server

Il processo motore di database utilizza i seguenti componenti per la ricerca in testo intero:

Componente Descrizione
Tabelle utenti In queste tabelle sono contenuti i dati da inserire nell'indice full-text.
Raccoglitore di testo completo Il componente di raccolta full-text opera con i thread di scansione full-text. È responsabile della pianificazione e della gestione del popolamento degli indici full-text, nonché del monitoraggio dei cataloghi full-text.
File del tesauro In questi file sono contenuti i sinonimi dei termini da cercare. Per altre informazioni, vedere Configurare e gestire i file del thesaurus per la ricerca full-text.
Oggetti della stoplist Gli oggetti stoplist contengono un elenco di parole comuni non utili per la ricerca. Per maggiori informazioni, consulta Configura e gestisce le parole stop e le liste di stop per Full-Text Ricerca.
motore di database query processor Query Processor consente di compilare ed eseguire query SQL. Se in una query SQL è inclusa una query di ricerca full-text, la query viene inviata al motore di ricerca full-text sia durante la compilazione sia durante l'esecuzione. Il risultato della query viene messo a confronto con l'indice full-text.
Motore di ricerca full-text Il Full-Text Engine nel motore di database è completamente integrato con il processore di query. Il motore di ricerca full-text compila ed esegue query full-text. Come parte dell'esecuzione di query, il motore di ricerca full-text può ricevere input dal thesaurus e dall'elenco di parole non significative.
Scrittore di indici (indicizzatore) Lo scrittore dell'indice costruisce la struttura utilizzata per memorizzare i token indicizzati.
Strumento di gestione del daemon di filtri Il gestore del daemon dei filtri è responsabile del monitoraggio dello stato dell'host del daemon dei filtri per il motore Full-Text.

Filtrare il processo host del daemon

Il processo host del daemon del filtro è un processo avviato dal Motore full-text. Esegue i seguenti componenti di ricerca full-text, responsabili dell'accesso ai dati delle tabelle, del relativo filtraggio e della suddivisione in parole, nonché della suddivisione in parole e dello stemming dell'input della query.

I componenti dell'host del daemon di filtri sono i seguenti:

Componente Descrizione
Gestore di protocollo Questo componente consente di effettuare il pull dei dati dalla memoria per un'ulteriore elaborazione e di accedere ai dati da una tabella utente in un database specificato. Una delle sue responsabilità è raccogliere dati dalle colonne sottoposte a indicizzazione full-text e passarli all'host del demone di filtro, che esegue il filtro e la suddivisione in parole come richiesto.
Filtri Alcuni tipi di dati richiedono un filtraggio prima che i dati in un documento possano essere indicizzati in testo completo. Questi tipi di dati includono dati in colonne varbinary(max), image o xml . Il filtro utilizzato per un documento dipende dal relativo tipo. Vengono infatti utilizzati filtri diversi per documenti di Microsoft Word (.doc), documenti di Microsoft Excel (.xls) e documenti XML (.xml). Il filtro estrae blocchi di testo dal documento, rimuove la formattazione incorporata e conserva il testo e, potenzialmente, informazioni sulla posizione del testo. Il risultato è un flusso di informazioni testuali. Per maggiori informazioni, consulta Configura e gestisce i filtri.
Word breaker e stemmer Un word breaker è un componente specifico della lingua che consente di trovare i delimitatori di parola in base alle regole lessicali di una determinata lingua (word breaking). Ogni word breaker è associato a un componente stemmer specifico per la lingua che coniuga i verbi ed esegue espansioni flessionali. In fase di indicizzazione, l'host del daemon di filtri utilizza un word breaker e uno stemmer per eseguire l'analisi linguistica sui dati testuali di una colonna di tabella specificata. Il word breaker e lo stemmer utilizzati per l'indicizzazione della colonna sono determinati dalla lingua associata a una colonna di tabella nell'indice full-text. Per ulteriori informazioni, vedere Configurare e gestire word breaker e stemmer.

SQL Server 2012 (11.x) installa una nuova versione dei word breaker e degli stemmer per l'inglese americano (LCID 1033) e l'inglese britannico (LCID 2057). Tuttavia, è possibile passare alla versione precedente di questi componenti se si vuole mantenere il comportamento precedente. Per ulteriori informazioni, vedere Modificare il separatore di parole usato per l'inglese americano e l'inglese britannico.

Elaborazione della ricerca a testo completo

La ricerca full-text si basa sul Full-Text Engine. Il motore full-text svolge due ruoli: il supporto per l'indicizzazione e l'esecuzione di query.

Indicizzazione del testo completo

Quando avvii una popolazione di testo completo (nota anche come crawl), il motore Full-Text spinge grandi quantità di dati in memoria e notifica all'host del daemon filtro. L'host filtra e divide i dati, convertendoli in liste di parole invertite. L'indicizzatore quindi estrae i dati convertiti dagli elenchi di parole, li elabora per rimuovere le parole non significative e memorizza gli elenchi di parole di un lotto in uno o più indici invertiti.

Quando si indicizzano dati memorizzati in una colonna xml, varbinary(max) o immagine, il filtro che implementa l'interfaccia IFilter estrae testo in base al formato file specificato per quei dati (ad esempio, Microsoft Word). In alcuni casi, i componenti del filtro richiedono che i dati binari vengano scritti nella FTData\FilterData cartella, invece di essere trasmessi direttamente in memoria.

Nell'ambito dell'elaborazione, i dati di testo raccolti vengono sottoposti a un word breaker per separare il testo in singoli token o parole chiave. La lingua usata per la tokenizzazione viene specificata a livello di colonna o può essere identificata all'interno dei dati varbinary(max), imageo xml dal componente filtro.

Potrebbe essere effettuata un'elaborazione aggiuntiva per rimuovere le parole stop e normalizzare i token prima che vengano memorizzati in un frammento di indice a testo completo.

Quando un popolamento è completo, viene attivato un processo finale di unione che riunisce i frammenti dell'indice in un unico indice full-text completo master. Questo processo consente di migliorare le prestazioni delle query perché è necessario eseguire query solo sull'indice master anziché su diversi frammenti di indice e è possibile usare statistiche di assegnazione dei punteggi migliori per la classificazione della pertinenza.

Processo di interrogazione del testo completo

Il Query Processor passa le porzioni full-text di una query al Motore Full-Text per l'elaborazione. Il motore full-text esegue la segmentazione delle parole e, facoltativamente, le espansioni del tesauro, lo stemming e l'elaborazione delle stopword (parole non significative). Le porzioni full-text della query sono rappresentate sotto forma di operatori SQL, principalmente come funzioni con valori di tabella in streaming (STVF). Durante l'esecuzione della query, queste STVF accedono all'indice invertito per recuperare i risultati corretti. I risultati vengono restituiti al client immediatamente oppure dopo essere stati ulteriormente elaborati.

Architettura degli indici full-text

Le informazioni contenute negli indici full-text vengono utilizzate dal motore di ricerca full-text per compilare query full-text che consentono di cercare rapidamente parole o combinazioni di parole specifiche in una tabella. In un indice full-text vengono archiviate informazioni su parole significative e sulla relativa posizione all'interno di una o più colonne di una tabella di database. Un indice full-text è un tipo speciale di indice funzionale basato su token compilato e gestito dal motore di ricerca full-text per SQL Server. Il processo di compilazione di un indice full-text è diverso da quello di altri tipi di indici. Anziché creare un albero B basato su un valore archiviato in una riga specifica, il motore di ricerca full-text compila una struttura con indice invertito, compresso e in pila dai singoli token dal testo indicizzato. Le dimensioni di un indice full-text sono limitate solo dalle risorse di memoria disponibili del computer in cui viene eseguita l'istanza di SQL Server.

A partire da SQL Server 2008 (10.0.x), gli indici full-text sono integrati nel motore di database anziché risiedere nel file system come nelle versioni precedenti di SQL Server. Per un nuovo database, il catalogo di testo completo è ora un oggetto virtuale che non appartiene a nessun file group. È semplicemente un concetto logico che si riferisce a un gruppo di indici del testo completo. Si noti però che durante l'aggiornamento di un database di SQL Server 2005 (9.x), per qualsiasi catalogo di testo completo che contiene file di dati, viene creato un nuovo gruppo di file. Per altre informazioni, vedere Upgrade Full-Text Search.

Ogni tabella può avere un solo indice a testo completo. Per creare un indice a testo completo su una tabella, la tabella deve avere una singola colonna non nulla, unica. Puoi costruire un indice full-text su colonne di tipo char, varchar, nchar, nvarchar, text, ntext, image, xml e varbinary(max). Quando crei un indice a testo completo su una colonna il cui tipo di dato è varbinary(max), image o xml, devi specificare una colonna di tipo. Una colonna del tipo è una colonna di tabella in cui è possibile archiviare l'estensione file (.doc, .pdf, .xls e così via) del documento in ogni riga.

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 articolo viene usato come esempio l'estratto seguente della tabella Document in AdventureWorks2025. In questo estratto sono visualizzate solo due colonne, la colonna DocumentID e la colonna Title e tre righe della tabella.

Per questo esempio, supponiamo che sia stato creato un indice a testo completo sulla Title colonna.

ID documento Titolo
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.

I dati sono stati invertiti dai documenti originali. L'inversione si verifica perché le parole chiave sono associate agli ID dei documenti. Per questo motivo, un indice full-text viene spesso definito come un indice invertito.

Si noti inoltre che la parola chiave and viene rimossa dall'indice full-text, perché and è una stopword. La rimozione di parole non significative da un indice full-text può comportare notevoli risparmi nello spazio su disco, migliorando così le prestazioni delle query. Per ulteriori informazioni sulle parole non significative, vedere Configurare e gestire le parole non significative ed elenchi di parole non significative per la ricerca full-text.

Frammento 1

Parola chiave ColId DocId Occorrenza
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 Keyword contiene la rappresentazione di un singolo token estratto al momento dell'indicizzazione. I word breaker determinano cosa costituisce un token.

La colonna ColId contiene un valore che corrisponde a una particolare colonna con indicizzazione full-text.

La colonna DocId contiene valori per un intero di 8 byte che corrisponde a un determinato valore della chiave full-text in una tabella con indice full-text. Questa mappatura è necessaria quando la chiave full-text non è di tipo di dati intero. 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 su queste 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 di mappatura DocId 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, esiste un elenco di valori di occorrenza che corrispondono agli offset relativi delle parole della parola chiave specifica 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 anche utili per calcolare i punteggi di rilevanza. Ad esempio, il numero di occorrenze di una parola chiave in a DocId potrebbe essere usato nel punteggio.

Frammenti dell'indice a testo completo

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 la tabella è soggetta al rilevamento automatico delle modifiche, viene creato un nuovo frammento.

ID documento Titolo
3 Rear Reflector

Nel seguente esempio, che mostra il Frammento 2, il frammento contiene dati più recenti circa DocId 3 rispetto al Frammento 1. Pertanto, quando l'utente esegue una query su Rear Reflector, i dati del Frammento 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 .

Frammento 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. Pertanto, un numero eccessivo di frammenti di indice full-text nell'indice full-text può causare un degrado significativo delle prestazioni delle query. Per ridurre il numero di frammenti, riorganizza il catalogo integrale utilizzando l'opzione REORGANIZE dell'istruzione ALTER FULLTEXT CATALOG Transact-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

Differenze tra indici full-text e indici SQL Server normali

Indici a testo completo Indici di SQL Server normali
È consentito un solo indice full-text per tabella. Sono consentiti più indici normali per tabella.
L'aggiunta di dati a indici full-text, definita popolamento, può essere richiesta in modo specifico, tramite pianificazione oppure può avvenire in modo automatico con l'aggiunta di nuovi dati. Vengono aggiornati automaticamente quando i dati su cui si basano vengono inseriti, aggiornati o eliminati.
Sono raggruppati all'interno dello stesso database in uno o più cataloghi full-text. Non sono raggruppati.

Full-Text Ricerca di componenti linguistici e supporto linguistico

La ricerca in testo completo supporta più di 50 lingue diverse, come inglese, spagnolo, cinese, giapponese, arabo, bangla e hindi. Per un elenco completo delle lingue full-text supportate, vedi sys.fulltext_languages. Ciascuna colonna contenuta nell'indice a testo completo è associata a un identificatore di Microsoft Windows locale (LCID) che corrisponde a una lingua supportata dalla ricerca a testo completo. Ad esempio, LCID 1033 corrisponde all'inglese statunitense, e LCID 2057 corrisponde all'inglese britannico. Per ogni lingua full-text supportata, il motore di database fornisce componenti linguistiche che supportano l'indicizzazione e l'interrogazione dei dati full-text memorizzati in quella lingua.

Tra i componenti specifici della lingua sono inclusi gli elementi seguenti:

Componente Descrizione
Word breaker e stemmer Un word breaker consente di trovare i delimitatori di parola in base alle regole lessicali di una determinata lingua (word breaking). A ogni separatore di parole è associato uno stemmer che coniuga i verbi della stessa lingua. Per altre informazioni, vedere Configurare e gestire i separatori di parole e gli algoritmi di stemming.
Liste di esclusione Viene fornita una stoplist di sistema, che contiene un insieme di base di parole vuote (note anche come parole non significative). Una stopword è una parola che non aiuta la ricerca ed è ignorata dalle query full-text. Ad esempio, per la lingua inglese, parole come a, and, is e the sono considerate parole vuote. In genere, è necessario configurare uno o più file di thesaurus ed elenchi di parole non significative. Per maggiori informazioni, consulta Configura e gestisce le parole stop e le liste di stop per Full-Text Ricerca.
File del tesauro Il motore di database installa anche un file thesaurus per ogni lingua a testo completo e un file thesaurus globale. I file del thesaurus installati sono vuoti, ma è possibile modificarli per definire sinonimi per una lingua o uno scenario aziendale specifico. Sviluppando un thesaurus basato sui dati full-text in uso, è possibile ampliare in modo efficace l'ambito delle query full-text su tali dati. Per altre informazioni, vedere Configurare e gestire i file del thesaurus per la ricerca full-text.
Filtri (IFilters) Per l'indicizzazione di un documento in una colonna del tipo di dati varbinary(max), imageo xml è richiesta l'applicazione di un filtro per eseguire altre operazioni di elaborazione. Il filtro deve essere specifico del tipo di documento (.doc, .pdf, .xls, .xml e così via). Per maggiori informazioni, consulta Configura e gestisce i filtri.