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, Contacts4
sono 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, Contacts4
campi.
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, Contacts4
campi in formato libero in cui probabilmente dovremmo rimuovere tutti tranne caratteri e spazi prima di cercare.
Usavamo LIKE
per la ricerca quando avevamo circa 1500 record e funzionava bene, ma ora abbiamo molti record e la LIKE
ricerca 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.com
come 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.com
sarà o (A) user
, gmail
e com
o (B) user
, user@gmail.com
, gmail
e 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ì.