Мы разрабатываем поиск как часть более крупной системы.
У нас есть 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 миллиард потраченных впустую персонажей.