2010-10-07 57 views
3

我试图通过电话号码搜索任何包含一些数字序列的电话号码。高效的数据库搜索LIKE'%something%'

显然将是缓慢的以下内容:

Select * from customer where phone like '%1234%' 

我需要的通配符,因为用户被允许在数据库中输入任何数据,因此它可能有国家代码,领先1(如请注意:我已经通过删除所有非数字字符来创建'已清除'的电话号码,所以我不需要担心破折号,空格等。

Isother是否有魔法让这样的搜索在合理的时间内运行?

+2

您正在使用哪个数据库(SQL Server,mysql,Oracle ...)? – adrianbanks 2010-10-07 23:17:01

+0

我应该提到我的MS SQL服务2008 – 2010-10-08 14:06:32

回答

2

如果你使用MySQL,你要寻找的全文搜索功能http://dev.mysql.com/doc/refman/5.1/en/fulltext-search.html

它专门优化查询,如您列出的一个,并且是相当不错的速度快,一旦成立。你需要MySQL中的数据,并且它必须在MyISAM表中(而不是InnoDB或其他)。

我在生产中使用它,它工作得很好。

+0

全文搜索绝对是一种方式。 – James 2010-10-07 23:24:00

+0

全文搜索是否在单个单词内工作? – 2010-10-08 00:11:05

+0

以有限的方式...有点警告。请参阅此处的*运算符http://dev.mysql.com/doc/refman/5.1/en/fulltext-boolean.html。基本上,您可以使用通配符,但只能在搜索词的结尾,而不能在前面。如果空间全部取出,我可以看到这是OP搜索问题的障碍 – Joshua 2010-10-08 01:28:46

1

没有。

如果你愿意,你可以创建一个索引表。这会有点贵,但也许是值得的。

所以,你可以把电话号码:2125551212在基于独特的子数不胜数的引用,并建立从倒排索引:

1 
2 
5 
12 
21 
25 
51 
55 
121 
125 
212 
255 
512 
551 
555 
1255 
2125 
2555 
5121 
5512 
5551 
12555 
21255 
25551 
55121 
55512 
125551 
212555 
255512 
555121 
1255512 
2125551 
2555121 
12555121 
21255512 
212555121 
2125551212 

因此,举例来说:

create table myindex (
    key varchar(10) not null, 
    datarowid integer not null references datarows(id) 
); 
create index i1myindex(key); 
insert into myindex values('1255', datarow.id); 

根据你想去多深。

例如,你可以只走4深,然后用4个数字扫描那些结果。因此,例如,如果您有“%123456%”,则可以询问带有“1234”的键,然后在结果集上应用完整表达式。

像:

select d.* from datarows d, myindex i where i.datarowid = d.id and i.key = '1234' and d.phone like "%123456%"; 

指数应该可以帮助你很快缩小了很多,数据库将扫描的余数。

很明显,你会在这里产生一些数据,但如果你查询了很多,你可以在这里做一些表现。