Ми розробляємо пошук як частину більшої системи.
У нас 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 мільйон ~ витрачених символів.