我们正在将搜索作为更大系统的一部分进行开发。
我们有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)
实际上,我们大约有10万条这样的记录。
我们希望用户可以指定电子邮件的一部分,例如“ @ 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
将是(A) user
,gmail
以及com
或(B) ,,user
和。REF:全文搜索的行为更改user@gmail.com
gmail
com
.
。
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)
这里?我从未听说过或遇到过一个名字长10亿个字符的人。并且,根据此答案,电子邮件地址不能超过254个字符;所以那里也有10亿个〜浪费的字符。