Ми розробляємо пошук як частину більшої системи.
У нас Microsoft SQL Server 2014 - 12.0.2000.8 (X64) Standard Edition (64-bit)із цим налаштуванням:
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- це структурований рядок цифр, розділених комами"77777777777, 88888888888"Email- це структурований рядок електронної пошти з комами типу"email1@gmail.com, email2@gmail.com"(або без коми взагалі подібними"email1@gmail.com")Contacts1, Contacts2, Contacts3, Contacts4- це текстові поля, де користувачі можуть вказувати контактні дані у вільній формі. Як"John Smith +1 202 555 0156"і"Bob, +1-999-888-0156, bob@company.com". Ці поля можуть містити електронні листи та телефони, які ми хочемо шукати далі.
Тут ми створюємо повнотекстові речі
-- 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
Ось зразок даних
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)
Насправді у нас є близько 100 тисяч таких записів.
Ми очікуємо, що користувачі можуть вказати частину електронної пошти, наприклад "@ gmail.com", і це повинно повертати всі рядки з електронними адресами Gmail у будь-якому з Email, Contacts1, Contacts2, Contacts3, Contacts4полів.
Те саме для номерів телефонів. Користувачі можуть шукати шаблон типу "70283", і запит повинен повертати телефони з цими цифрами. Навіть для Contacts1, Contacts2, Contacts3, Contacts4полів вільної форми, де ми, мабуть, повинні спочатку видалити всі, крім цифр та пробілів, перш ніж шукати.
Ми використовували LIKEдля пошуку, коли у нас було близько 1500 записів, і це працювало чудово, але зараз у нас багато записів, і LIKEпошук займає нескінченно, щоб отримати результати.
Ось як ми намагаємося отримати дані звідти:
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як пошуковий термін, оскільки @символ - це переривник слів. Іншими словами, в залежності від версії SQL Server у вас є, слова в індексі для user@gmail.comбуде або (А) user, gmailі comчи (B) user, user@gmail.com, gmailі com. REF: Зміни в поведінці до повнотекстового пошуку
..
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+'%')Створіть приблизно п’ять індивідуальних індексів у кожному з полів і включіть первинний ключ.
nvarchar(MAX)? Я ніколи не чув і не зустрічав когось із ім’ям, яке має 1 мільярд ~ символів. Відповідно до цієї відповіді , адреса електронної пошти не може бути довше 254 символів; тому у вас також є 1 мільйон ~ витрачених символів.