Stiamo sviluppando una ricerca come parte di un sistema più grande.
Abbiamo Microsoft SQL Server 2014 - 12.0.2000.8 (X64) Standard Edition (64-bit)con questa configurazione:
CREATE TABLE NewCompanies(
[Id] [uniqueidentifier] NOT NULL,
[Name] [nvarchar](400) NOT NULL,
[Phone] [nvarchar](max) NULL,
[Email] [nvarchar](max) NULL,
[Contacts1] [nvarchar](max) NULL,
[Contacts2] [nvarchar](max) NULL,
[Contacts3] [nvarchar](max) NULL,
[Contacts4] [nvarchar](max) NULL,
[Address] [nvarchar](max) NULL,
CONSTRAINT PK_Id PRIMARY KEY (Id)
);
Phoneè una stringa di cifre separate da virgola strutturata come"77777777777, 88888888888"Emailè una stringa di email strutturata con virgole simili"email1@gmail.com, email2@gmail.com"(o senza virgole affatto simili"email1@gmail.com")Contacts1, Contacts2, Contacts3, Contacts4sono campi di testo in cui gli utenti possono specificare i dettagli di contatto in forma libera. Come"John Smith +1 202 555 0156"o"Bob, +1-999-888-0156, bob@company.com". Questi campi possono contenere e-mail e telefoni che vogliamo cercare ulteriormente.
Qui creiamo materiale full-text
-- FULL TEXT SEARCH
CREATE FULLTEXT CATALOG NewCompanySearch AS DEFAULT;
CREATE FULLTEXT INDEX ON NewCompanies(Name, Phone, Email, Contacts1, Contacts2, Contacts3, Contacts4, Address)
KEY INDEX PK_Id
Ecco un esempio di dati
INSERT INTO NewCompanies(Id, Name, Phone, Email, Contacts1, Contacts2, Contacts3, Contacts4)
VALUES ('7BA05F18-1337-4AFB-80D9-00001A777E4F', 'PJSC Azimuth', '79001002030, 78005005044', 'regular@hotmail.com, s.m.s@gmail.com', 'John Smith', 'Call only at weekends +7-999-666-22-11', NULL, NULL)
In realtà abbiamo circa 100 mila di tali record.
Ci aspettiamo che gli utenti possano specificare una parte dell'email come "@ gmail.com" e questo dovrebbe restituire tutte le righe con indirizzi email Gmail in uno qualsiasi dei Email, Contacts1, Contacts2, Contacts3, Contacts4campi.
Lo stesso per i numeri di telefono. Gli utenti possono cercare un modello come "70283" e una query dovrebbe restituire i telefoni con queste cifre al loro interno. È anche per i Contacts1, Contacts2, Contacts3, Contacts4campi in formato libero in cui probabilmente dovremmo rimuovere tutti tranne caratteri e spazi prima di cercare.
Usavamo LIKEper la ricerca quando avevamo circa 1500 record e funzionava bene, ma ora abbiamo molti record e la LIKEricerca impiega infiniti per ottenere risultati.
Ecco come proviamo a ottenere dati da lì:
SELECT * FROM NewCompanies WHERE CONTAINS((Email, Contacts1, Contacts2, Contacts3, Contacts4), '"s.m.s@gmail.com*"') -- this doesn't get the row
SELECT * FROM NewCompanies WHERE CONTAINS((Phone, Contacts1, Contacts2, Contacts3, Contacts4), '"6662211*"') -- doesn't get anything
SELECT * FROM NewCompanies WHERE CONTAINS(Name, '"zimuth*"') -- doesn't get anything
@gmail.comcome termine di ricerca perché il @personaggio è un word breaker. In altre parole, a seconda della versione di SQL Server che hai, parole l'indice user@gmail.comsarà o (A) user, gmaile como (B) user, user@gmail.com, gmaile com. RIF: modifiche del comportamento alla ricerca full-text
..
SELECT * FROM NewCompanies WHERE Id IN (SELECT ID from .... where MyOuterApply.EmailCol1 LIKE '%'+@SearchString+'%') OR Id IN (SELECT ID from .... where MyOuterApply.EmailCol2 LIKE '%'+@SearchString+'%')Crea circa cinque singoli indici su ciascuno dei campi e includi la chiave primaria
nvarchar(MAX)qui? Non ho mai sentito parlare o incontrato qualcuno che si chiama ha una lunghezza di 1 miliardo di caratteri. E, secondo questa risposta , un indirizzo e-mail non può contenere più di 254 caratteri; quindi hai anche 1 miliardo di personaggi ~ sprecati lì.